Http協議與請求, Post請求與Get請求的區別,Base64和URL編碼,md5,sha-1加密,對稱和非對稱加密,支付寶微信第三方支付
阿新 • • 發佈:2019-02-01
Http協議與請求 Post請求 Post請求與Get請求的區別 Get請求的引數是直接放在url後面的,而Post請求是放在請求體中的 Get請求引數的長度會根據瀏覽器的不同實現有一定限制,而Post請求引數長度沒有限制 Get請求方便測試,直接輸入地址即可,而Post請求不方便測試,需要藉助程式碼或者工具進行傳送 Get請求和Post請求沒有本質的區別,只是定義上的區別,比如如果你非要將get方式的引數放在請求體中,那麼伺服器也是可以接收處理的,同樣,你也可以將post方式的引數拼在url後面 Post請求的使用場景 使用Post請求上傳鍵值對 使用Post請求上傳json串 使用Post請求上傳單個檔案 使用Post請求上傳多個檔案 使用Post方法上傳鍵值對,程式碼如下: public void asyncPost(String url,HashMap<String, String> params,TextHttpResponseHandler responseHandler){ RequestParams requestParams = new RequestParams(params); asyncHttpClient.post(url, requestParams, responseHandler); } /** * post提交key-value * @param url2 */ private void postKeyValue(String url) { HashMap<String, String> params = new HashMap<String, String>(); params.put("username", "俊哥"); params.put("password", "111"); HttpHelper.get().asyncPost(url, params, new TextHttpResponseHandler() { @Override public void onSuccess(int arg0, Header[] arg1, String text) { tv_result.setText(text); } @Override public void onFailure(int arg0, Header[] arg1, String arg2, Throwable arg3) { } }); } 使用Post方式上傳檔案,程式碼如下: public void asyncUploadFile(String url, String key, File file,TextHttpResponseHandler responseHandler) { RequestParams requestParams = new RequestParams(); try { requestParams.put(key, file); asyncHttpClient.post(url,requestParams , responseHandler); } catch (FileNotFoundException e) { e.printStackTrace(); } } private void uploadFile() { try { File file = new File(Environment.getExternalStorageDirectory()+"/dog.jpg"); HttpHelper.get().asyncUploadFile(upload, "file", file, new TextHttpResponseHandler() { @Override public void onSuccess(int arg0, Header[] arg1, String text) { tv_result.setText(text); } @Override public void onFailure(int arg0, Header[] arg1, String arg2, Throwable arg3) { } }); } catch (Exception e) { e.printStackTrace(); } } Post請求相關注意事項: 傳遞中文引數問題,Get請求同樣需要注意,需要對url進行編碼,對應的類有URLEncoder和URLDecoder,否則會亂碼,當然很多第三方http庫已經處理該問題 常見Content-Type定義: 普通文字:text/plain 表單鍵值對:application/x-www-form-urlencoded 檔案資料:application/octet-stream json資料:application/json xml資料:text/xml Android中常見編碼Base64和URL編碼 URL編碼:http協議中請求的url不支援中文和特殊字元(如&?),所以需要對url進行編碼和解碼,編碼使用的是URLEncoder,解碼使用的是URLDecoder; //進行url編碼 URLEncoder.encode(url) //進行url解碼 URLDecoder.decode(encodeUrl) Base64:可以將二進位制資料物件轉為字串,主要用於在http傳輸中將一些比較大的比如二進位制資料,編碼為字串,適合放入url進行傳遞,而且具有非明文行。應用場景如下: 將檔案進行base64編碼為字串後再上傳,程式碼如下: private void base64Image() { Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher); ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(CompressFormat.PNG, 100, baos); byte[] encode = Base64.encode(baos.toByteArray(), Base64.DEFAULT); tv_result.setText(new String(encode)); } 將物件進行base64編碼為字串後,可以進行本地快取,程式碼如下: private void base64Object() { Object obj = new Object(); ByteArrayOutputStream bo = new ByteArrayOutputStream(); ObjectOutputStream oo; try { oo = new ObjectOutputStream(bo); oo.writeObject(obj); } catch (IOException e) { e.printStackTrace(); } byte[] encode = Base64.encode(bo.toByteArray(), Base64.DEFAULT); tv_result.setText(new String(encode)); } Android中的數字摘要,加密和解密 數字摘要:是指通過演算法將長資料變為短資料,通常用來標識資料的唯一性,是否被修改,常用的加密演算法有md5和sha1,如安卓app的簽名也是用這2種演算法計算的; md5由於具有不可逆性,也被用來作為密碼加密,並且通常情況下為了讓加密過程變的不可預測,我們會進行加鹽操作,程式碼如下: /** * 使用md5方式進行加密 * @return */ private String md5(String password) { StringBuffer sb = new StringBuffer(); try { MessageDigest messageDigest = MessageDigest.getInstance("MD5"); messageDigest.update(password.getBytes()); byte[] digest = messageDigest.digest(); for (int i = 0; i < digest.length; i++) { String str = Integer.toHexString(digest[i] & 0xff); if (str.length() == 1) { str = str + "0"; } sb.append(str); } } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return sb.toString(); } sha1也不可逆,比md5長度更長,所以更安全,但是加密的效率比md5要慢一些,如檔案的秒傳功能,以及相同的v4包衝突都是根據檔案的sha1值進行比對的。 /** * 使用sha-1方式進行加密 * @return */ private String sha1(String password) { StringBuffer sb = new StringBuffer(); try { MessageDigest messageDigest = MessageDigest.getInstance("SHA-1"); messageDigest.update(password.getBytes()); byte[] digest = messageDigest.digest(); for (int i = 0; i < digest.length; i++) { String str = Integer.toHexString(digest[i] & 0xff); if (str.length() == 1) { str = str + "0"; } sb.append(str); } } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return sb.toString(); }
加密和解密,一般分為對稱加密和非對稱加密 對稱加密: 金鑰可以自己指定,只有一把金鑰,如果金鑰暴露,檔案就會被暴露, 常見對稱加密演算法有DES演算法(Data Encryption Standard)和AES演算法(Advanced Encryption Standard), 特點是加密速度很快,但是缺點是安全性較低,因為只要金鑰暴漏,資料就可以被解密了。 非對稱加密:有兩把鑰匙(金鑰對),公鑰和私鑰,公鑰的話給別人,私鑰自己儲存 常見非對稱加密演算法是RSA 2把金鑰通常是通過程式生成,不能自己指定 特點是加密速度慢些,但是安全係數很高 加密和解密的規則是:公鑰加密只能私鑰解密,私鑰加密只能公鑰解密 應用場景舉例:在整合支付寶支付sdk時,需要生成私鑰和公鑰,公鑰需要設定到支付寶網站的管理後臺,在程式中呼叫支付介面的時候,使用我們自己的私鑰進行加密,這樣支付寶由於有公鑰可以解密,其他人即時劫持了資料,但是沒有公鑰,也無法解密。 程式碼實踐,使用hmAndroidUtils中的工具類進行操作 DES加密和解密的程式碼如下:
String data = "我是俊哥"; String desKey = "青龍偃月刀";// 金鑰,口號 boolean isDesEncrypt = false; private void useDes() { try { if(isDesEncrypt){ //解密 text.setText(Des.decrypt(text.getText().toString(), desKey)); }else { //加密 text.setText(Des.encrypt(data, desKey)); } isDesEncrypt = !isDesEncrypt; } catch (Exception e) { e.printStackTrace(); } } RSA加密和解密的程式碼如下: //1.生成金鑰對,設計口號 try { Map<String, Object> genKeyPair = RSACrypt.genKeyPair(); //2.獲取公鑰 publicKey = RSACrypt.getPublicKey(genKeyPair); //3.獲取私鑰 privateKey = RSACrypt.getPrivateKey(genKeyPair); } catch (Exception e) { e.printStackTrace(); } private boolean isRSAEncrypt = false; protected void useRSA() { try { if(isRSAEncrypt){ //公鑰解密 String str = text.getText().toString(); byte[] bs = RSACrypt.decryptByPublicKey(RSACrypt.decode(str), publicKey); text.setText(new String(bs)); }else { //私鑰加密 byte[] bs = RSACrypt.encryptByPrivateKey(data.getBytes(), privateKey); text.setText(RSACrypt.encode(bs)); } isRSAEncrypt = !isRSAEncrypt; } catch (Exception e) { e.printStackTrace(); } }