欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Android端與JavaWeb傳輸加密(DES+RSA)

 更新時(shí)間:2017年11月03日 17:20:41   作者:阿犇專用  
這篇文章主要介紹了詳解Android端與JavaWeb傳輸加密(DES+RSA),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧

一、加密介紹

本文采用對(duì)稱式加密算法DES和非對(duì)稱式加密算法RSA結(jié)合做數(shù)據(jù)傳輸加密的方式。

先說(shuō)一下對(duì)稱式加密 DES:對(duì)稱式加密即使用單鑰密碼加密的方法,信息的加密和解密使用同一個(gè)秘鑰,這種方式也稱為單秘鑰加密。所謂對(duì)稱就是指加密和解密使用的是同一個(gè)秘鑰!

常用的對(duì)稱加密有:DES、IDEA、RC2、RC4、SKIPJACK、RC5、AES算法等。

與對(duì)稱加密算法不同,非對(duì)稱加密算法需要兩個(gè)密鑰:公開密鑰(publickey)和私有密鑰 (privatekey)。公開密鑰與私有密鑰是一對(duì),如果用公開密鑰對(duì)數(shù)據(jù)進(jìn)行加密,只有用對(duì)應(yīng)的私有密鑰才能解密;如果用私有密鑰對(duì)數(shù)據(jù)進(jìn)行加密,那么只有用對(duì)應(yīng)的公開密鑰才能解密。因?yàn)榧用芎徒饷苁褂玫氖莾蓚€(gè)不同的密鑰,所以這種算法叫作非對(duì)稱加密算法。

RSA 公鑰加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美國(guó)麻省理工學(xué)院)開發(fā)的。RSA取名來(lái)自開發(fā)他們?nèi)叩拿?。RSA是目前最有影響力的公鑰加密算法,它能夠抵抗到目前為止已知的所有密碼攻擊,已被ISO推薦為公鑰數(shù)據(jù)加密標(biāo)準(zhǔn)。 RSA算法基于一個(gè)十分簡(jiǎn)單的數(shù)論事實(shí):將兩個(gè)大素?cái)?shù)相乘十分容易,但那時(shí)想要對(duì)其乘積進(jìn)行因式分解卻極其困難,因此可以將乘積公開作為加密密鑰。

二、RSA密鑰生成

RSA密鑰采用OpenSSL協(xié)議進(jìn)行生成,本文僅簡(jiǎn)單生成公鑰和私鑰,如有其它需要可以通過CA證書進(jìn)行密鑰的生成

1、OpenSSL安裝

http://slproweb.com/products/Win32OpenSSL.html

請(qǐng)自行選擇32位64位進(jìn)行下載安裝

2、打開工作空間

打開OpenSSL安裝目錄下的bin,運(yùn)行OpenSSL.exe進(jìn)入OpenSSL工作空間

3、密鑰生成

①、私鑰生成(生成位置位于bin目錄下)

genrsa -out rsa_private_key.pem 1024

openssl隨機(jī)生成了一份私鑰,加密長(zhǎng)度是1024位。加密長(zhǎng)度是指理論上最大允許”被加密的信息“長(zhǎng)度的限制,也就是明文的長(zhǎng)度限制。隨著這個(gè)參數(shù)的增大(比方說(shuō)2048),允許的明文長(zhǎng)度也會(huì)增加,但同時(shí)也會(huì)造成計(jì)算復(fù)雜度的極速增長(zhǎng)。一般推薦的長(zhǎng)度就是1024位(128字節(jié))

JAVA需要使用的私鑰需要經(jīng)過PKCS#8編碼,PHP程序不需要

當(dāng)前私鑰格式需要轉(zhuǎn)換為pkcs#8的格式,命令為:

pkcs8 -topk8 -inform PEM -in pkcs8_rsa_private_key.pem -outform PEM -nocrypt

②、公鑰生成

rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout

至此,RSA+DES相關(guān)前期準(zhǔn)備工作完成

三、Android端配置

本文主要針對(duì)數(shù)據(jù)傳輸過程進(jìn)行加密,采取加密Json字符串完成整個(gè)加密過程,由此,需要統(tǒng)一傳輸參數(shù)為"data=********&sign="*******************"的格式,如有其它需求請(qǐng)自行更改。

由于本項(xiàng)目網(wǎng)絡(luò)框架采用Retrofit+OkHttp的實(shí)現(xiàn)方式,所以對(duì)參數(shù)進(jìn)行加密的過程由OkHttp攔截器來(lái)實(shí)現(xiàn)

public class EncryptionInterceptor implements Interceptor {

private Context mContext;

public EncryptionInterceptor(Context context) {
 this.mContext = context;
}

@Override
public Response intercept(@NonNull Chain chain) throws IOException {
 Request request = chain.request();
 RequestBody oldBody = request.body();
 Buffer buffer = new Buffer();
 if (oldBody != null) {
  oldBody.writeTo(buffer);
 }
 String strOldBody = buffer.readUtf8();
 Map<String, String> map = new HashMap<>();
 String dataByte = URLDecoder.decode(strOldBody.substring(5), "utf-8");
 try {
  //獲取DES的key
  byte[] desKey = DESCoder.initKey();
  //DES加密數(shù)據(jù)
  byte[] encrypt = DESCoder.encrypt(dataByte.getBytes(), desKey);
  map.put("data", parseByte2HexStr(encrypt));
  //RSA加密
  RSAEncrypt rsaEncrypt = new RSAEncrypt();
  InputStream inputStream =  mContext.getResources().getAssets().open("rsa_public_key.pem");
  //rsa設(shè)置公鑰
  rsaEncrypt.loadPublicKey(inputStream);
  //rsa加密DES的key
  byte[] rsaData = rsaEncrypt.encrypt(rsaEncrypt.getPublicKey(), desKey);
  map.put("sign", parseByte2HexStr(rsaData));
 } catch (Exception e) {
  e.printStackTrace();
 }

 FormBody body = new FormBody.Builder().add("data", map.get("data")).add("sign", map.get("sign")).build();
 request = request.newBuilder().header("Content-Type", body.contentType().type()).header("Content-Length", String.valueOf(body.contentLength())).method(request.method(), body).build();
 return chain.proceed(request);
}

/**
 * 將二進(jìn)制轉(zhuǎn)換成16進(jìn)制
 *
 * @since v1.0
 */
private static String parseByte2HexStr(byte buf[]) {
 StringBuilder sb = new StringBuilder();
 for (byte aBuf : buf) {
  String hex = Integer.toHexString(aBuf & 0xFF);
  if (hex.length() == 1) {
   hex = '0' + hex;
  }
  sb.append(hex.toUpperCase());
 }
 return sb.toString();
}

/**
 * 按照key排序得到參數(shù)列表字符串
 *
 * @param paramValues 參數(shù)map對(duì)象
 * @return 參數(shù)列表字符串
 */
public static String getParamsOrderByKey(Map<String, String> paramValues) {
 String params = "";
 List<String> paramNames = new ArrayList<>(paramValues.size());
 paramNames.addAll(paramValues.keySet());
 Collections.sort(paramNames);
 for (String paramName : paramNames) {

  if (params.equals("")) {
   params += paramName + "=" + paramValues.get(paramName);
  } else {
   params += "&" + paramName + "=" + paramValues.get(paramName);
  }
 }

 return params;
}

/**
 * 將16進(jìn)制轉(zhuǎn)換為二進(jìn)制
 *
 * @since v1.0
 */
public byte[] parseHexStr2Byte(String hexStr) {
 if (hexStr.length() < 1)
  return null;
 byte[] result = new byte[hexStr.length() / 2];
 for (int i = 0; i < hexStr.length() / 2; i++) {
  int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
  int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
  result[i] = (byte) (high * 16 + low);
 }
 return result;
}

}

添加OkHttp攔截器

new OkHttpClient.Builder()
    .addInterceptor(new EncryptionInterceptor(this))
    .build();

RSA工具類實(shí)現(xiàn)

public class RSAEncrypt {
public static final String DEFAULT_PUBLIC_KEY =
  "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1Qcf1zVOuhseFxvo6+FnVvEPs" + "\r" + "Uvczg6oX+HjMNksiiDWcNkbPHfznaPDtgoBY2xF0R8HGHbrT53LNvkj7UMcI48tq" + "\r" + "K+B4YdJHe9SgJVDCCiceLLGtf/ev206qJ/XgKgrLFD+vMmjIB8gQCkZvy/dxhEf1" + "\r" + "aAmoz5tdJhOVdxT7QwIDAQAB" + "\r";

public static final String DEFAULT_PRIVATE_KEY =
  "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALVBx/XNU66Gx4XG" + "\r" +
    "+jr4WdW8Q+xS9zODqhf4eMw2SyKINZw2Rs8d/Odo8O2CgFjbEXRHwcYdutPncs2+" + "\r" +
    "SPtQxwjjy2or4Hhh0kd71KAlUMIKJx4ssa1/96/bTqon9eAqCssUP68yaMgHyBAK" + "\r" +
    "Rm/L93GER/VoCajPm10mE5V3FPtDAgMBAAECgYAf1hEAHHNhSS0MUzmqV+q3ftzT" + "\r" +
    "SnM+6hZbJXpaLAMgapo3+NSRFmxQXP9MSEqw0LGNIfloCdrB03o3pv98nOCIZCh7" + "\r" +
    "PHsU2GhxJ04Qro+wKhK358326KNXCjjqVIBG0xMbJxVhjM2/jjfocxFpe5iD7h53" + "\r" +
    "c+GvDgUVduAYO4I1GQJBAO21n2aIzQV3mScS1O8BRV+9CmHaDbVHqBetRoB3kJ2U" + "\r" +
    "piflKTNofwWmTA5A8sKt8WcOz7LsB2SWcp9jNvatxA8CQQDDNCmfo6eix9e5f11K" + "\r" +
    "Rf8sRiN7XGDzlKkZlmQAN0UtXdTP4AN9cuZrwnntWKysXr/zLntYLGYn9rdrohbD" + "\r" +
    "9RGNAkBOEsog7iuQcSCfQcMoIN29PSSs0OaRtNBTvniadyrLZuhP0CeBGAAoRd9T" + "\r" +
    "CyfwoxrXg3jaRkWDVxqcmQSTbq0nAkB8flcRhilSqsuNdYpE5VFxpiXY9jirAKO8" + "\r" +
    "Our6LEXFQjOIhCEVr+L+1OA4HDa8FA2thXaK7H4WfMXMMmr8fN69AkEAuR0YU9My" + "\r" +
    "snzWLDWYR5sNp90PhyDSL/HTZHBnebD+JlAYwoYRFYt+tXw0/PEmV2B3thYGPeiZ" + "\r" +
    "kHKd/TeLIVbxGg==" + "\r";

/**
 * 私鑰
 */
private RSAPrivateKey privateKey;

/**
 * 公鑰
 */
private RSAPublicKey publicKey;

/**
 * 字節(jié)數(shù)據(jù)轉(zhuǎn)字符串專用集合
 */
private static final char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};


/**
 * 獲取私鑰
 *
 * @return 當(dāng)前的私鑰對(duì)象
 */
public RSAPrivateKey getPrivateKey() {
 return privateKey;
}

/**
 * 獲取公鑰
 *
 * @return 當(dāng)前的公鑰對(duì)象
 */
public RSAPublicKey getPublicKey() {
 return publicKey;
}

/**
 * 隨機(jī)生成密鑰對(duì)
 */
public void genKeyPair() {
 KeyPairGenerator keyPairGen = null;
 try {
  keyPairGen = KeyPairGenerator.getInstance("RSA");
 } catch (NoSuchAlgorithmException e) {
  e.printStackTrace();
 }
 keyPairGen.initialize(1024, new SecureRandom());
 KeyPair keyPair = keyPairGen.generateKeyPair();
 this.privateKey = (RSAPrivateKey) keyPair.getPrivate();
 this.publicKey = (RSAPublicKey) keyPair.getPublic();
}

/**
 * 從文件中輸入流中加載公鑰
 *
 * @param in 公鑰輸入流
 * @throws Exception 加載公鑰時(shí)產(chǎn)生的異常
 */
public void loadPublicKey(InputStream in) throws Exception {
 try {
  BufferedReader br = new BufferedReader(new InputStreamReader(in));
  String readLine = null;
  StringBuilder sb = new StringBuilder();
  while ((readLine = br.readLine()) != null) {
   if (readLine.charAt(0) == '-') {
    continue;
   } else {
    sb.append(readLine);
    sb.append('\r');
   }
  }
  loadPublicKey(sb.toString());
 } catch (IOException e) {
  throw new Exception("公鑰數(shù)據(jù)流讀取錯(cuò)誤");
 } catch (NullPointerException e) {
  throw new Exception("公鑰輸入流為空");
 }
}


/**
 * 從字符串中加載公鑰
 *
 * @param publicKeyStr 公鑰數(shù)據(jù)字符串
 * @throws Exception 加載公鑰時(shí)產(chǎn)生的異常
 */
public void loadPublicKey(String publicKeyStr) throws Exception {
 try {
 // byte[] buffer = Base64.decode(publicKeyStr.getBytes(), Base64.DEFAULT);
  BASE64Decoder base64Decoder= new BASE64Decoder();
  byte[] buffer= base64Decoder.decodeBuffer(publicKeyStr);
  KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
  this.publicKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);
 } catch (NoSuchAlgorithmException e) {
  throw new Exception("無(wú)此算法");
 } catch (InvalidKeySpecException e) {
  throw new Exception("公鑰非法");
 } catch (NullPointerException e) {
  throw new Exception("公鑰數(shù)據(jù)為空");
 }
}

/**
 * 從文件中加載私鑰
 *
 * @return 是否成功
 * @throws Exception
 */
public void loadPrivateKey(InputStream in) throws Exception {
 try {
  BufferedReader br = new BufferedReader(new InputStreamReader(in));
  String readLine = null;
  StringBuilder sb = new StringBuilder();
  while ((readLine = br.readLine()) != null) {
   if (readLine.charAt(0) == '-') {
    continue;
   } else {
    sb.append(readLine);
    sb.append('\r');
   }
  }
  loadPrivateKey(sb.toString());
 } catch (IOException e) {
  throw new Exception("私鑰數(shù)據(jù)讀取錯(cuò)誤");
 } catch (NullPointerException e) {
  throw new Exception("私鑰輸入流為空");
 }
}

public void loadPrivateKey(String privateKeyStr) throws Exception {
 try {
  //byte[] buffer = Base64.encode(privateKeyStr.getBytes(), Base64.DEFAULT);
  BASE64Decoder base64Decoder= new BASE64Decoder();
  byte[] buffer= base64Decoder.decodeBuffer(privateKeyStr);
  PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
  KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  this.privateKey = (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
 } catch (NoSuchAlgorithmException e) {
  throw new Exception("無(wú)此算法");
 } catch (InvalidKeySpecException e) {
  throw new Exception("私鑰非法");
 } catch (NullPointerException e) {
  throw new Exception("私鑰數(shù)據(jù)為空");
 }
}

/**
 * 加密過程
 *
 * @param publicKey  公鑰
 * @param plainTextData 明文數(shù)據(jù)
 * @return
 * @throws Exception 加密過程中的異常信息
 */
public byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData) throws Exception {
 if (publicKey == null) {
  throw new Exception("加密公鑰為空, 請(qǐng)?jiān)O(shè)置");
 }
 Cipher cipher = null;
 try {
  
  cipher = Cipher.getInstance("RSA");
  //Android端無(wú)需添加此加密提供者,已默認(rèn)實(shí)現(xiàn)
  //cipher = Cipher.getInstance("RSA", new BouncyCastleProvider());
  cipher.init(Cipher.ENCRYPT_MODE, publicKey);
  return cipher.doFinal(plainTextData);
 } catch (NoSuchAlgorithmException e) {
  throw new Exception("無(wú)此加密算法");
 } catch (NoSuchPaddingException e) {
  e.printStackTrace();
  return null;
 } catch (InvalidKeyException e) {
  throw new Exception("加密公鑰非法,請(qǐng)檢查");
 } catch (IllegalBlockSizeException e) {
  throw new Exception("明文長(zhǎng)度非法");
 } catch (BadPaddingException e) {
  throw new Exception("明文數(shù)據(jù)已損壞");
 }
}

/**
 * 解密過程
 *
 * @param privateKey 私鑰
 * @param cipherData 密文數(shù)據(jù)
 * @return 明文
 * @throws Exception 解密過程中的異常信息
 */
public byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData) throws Exception {
 if (privateKey == null) {
  throw new Exception("解密私鑰為空, 請(qǐng)?jiān)O(shè)置");
 }
 Cipher cipher = null;
 try {
  cipher = Cipher.getInstance("RSA");
  //Android端無(wú)需添加此加密提供者,已默認(rèn)實(shí)現(xiàn)
  //cipher = Cipher.getInstance("RSA", new BouncyCastleProvider());
  cipher.init(Cipher.DECRYPT_MODE, privateKey);
  byte[] output = cipher.doFinal(cipherData);
  return output;
 } catch (NoSuchAlgorithmException e) {
  throw new Exception("無(wú)此解密算法");
 } catch (NoSuchPaddingException e) {
  e.printStackTrace();
  return null;
 } catch (InvalidKeyException e) {
  throw new Exception("解密私鑰非法,請(qǐng)檢查");
 } catch (IllegalBlockSizeException e) {
  throw new Exception("密文長(zhǎng)度非法");
 } catch (BadPaddingException e) {
  throw new Exception("密文數(shù)據(jù)已損壞");
 }
}


/**
 * 字節(jié)數(shù)據(jù)轉(zhuǎn)十六進(jìn)制字符串
 *
 * @param data 輸入數(shù)據(jù)
 * @return 十六進(jìn)制內(nèi)容
 */
public static String byteArrayToString(byte[] data) {
 StringBuilder stringBuilder = new StringBuilder();
 for (int i = 0; i < data.length; i++) {
  //取出字節(jié)的高四位 作為索引得到相應(yīng)的十六進(jìn)制標(biāo)識(shí)符 注意無(wú)符號(hào)右移 
  stringBuilder.append(HEX_CHAR[(data[i] & 0xf0) >>> 4]);
  //取出字節(jié)的低四位 作為索引得到相應(yīng)的十六進(jìn)制標(biāo)識(shí)符 
  stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]);
  if (i < data.length - 1) {
   stringBuilder.append(' ');
  }
 }
 return stringBuilder.toString();
}


public static void main(String[] args) {
 RSAEncrypt rsaEncrypt = new RSAEncrypt();

 //加載公鑰
 try {
  rsaEncrypt.loadPublicKey(RSAEncrypt.DEFAULT_PUBLIC_KEY);
  System.out.println("加載公鑰成功");
 } catch (Exception e) {
  System.err.println(e.getMessage());
  System.err.println("加載公鑰失敗");
 }
 /*try {
  rsaEncrypt.loadPublicKey(RSAEncrypt.DEFAULT_PUBLIC_KEY);
  System.out.println("加載公鑰成功");
 } catch (Exception e) {
  System.err.println(e.getMessage());
  System.err.println("加載公鑰失敗");
 }
 //加載私鑰
 try {
  rsaEncrypt.loadPrivateKey(RSAEncrypt.DEFAULT_PRIVATE_KEY);
  System.out.println("加載私鑰成功");
 } catch (Exception e) {
  System.err.println(e.getMessage());
  System.err.println("加載私鑰失敗");
 }
 try {
  SecureRandom sr = new SecureRandom();
  KeyGenerator kg = KeyGenerator.getInstance("DES");
  kg.init(56, sr);
  SecretKey generateKey = kg.generateKey();
  String encodeHexString = Hex.toHexString(generateKey.getEncoded());
  System.out.println(encodeHexString);
 } catch (NoSuchAlgorithmException e) {
  e.printStackTrace();
 }
 //測(cè)試字符串
 String encryptStr= "Test String chaijunkun";

 try {
  //加密
  long encryptStart = System.currentTimeMillis();
  byte[] cipher = rsaEncrypt.encrypt(rsaEncrypt.getPublicKey(), encryptStr.getBytes());
  long encryptEnd = System.currentTimeMillis();
  System.out.println("密文長(zhǎng)度:"+ cipher.length);
  System.out.println(RSAEncrypt.byteArrayToString(cipher));
  System.out.println("加密時(shí)間"+ (encryptEnd-encryptStart));

  //解密
  long decryptStart = System.currentTimeMillis();
  byte[] plainText = rsaEncrypt.decrypt(rsaEncrypt.getPrivateKey(), cipher);
  long decryptEnd = System.currentTimeMillis();
  System.out.println("明文長(zhǎng)度:"+ plainText.length);
  System.out.println(RSAEncrypt.byteArrayToString(plainText));
  System.out.println("解密時(shí)間"+ (decryptEnd-decryptStart));

  System.out.println(new String(plainText));
 } catch (Exception e) {
  System.err.println(e.getMessage());
 }*/ 
  }
} 

DES工具類實(shí)現(xiàn)

public class DESCoder {
/**
 * 密鑰算法
 * java 7只支持56位密鑰
 * Bouncy Castle 支持64位密鑰
 */
public static final String KEY_ALGORITHM = "DES";
/**
 * 加密/解密算法 /工作模式/填充方式
 */
public static final String CIPHER_ALGORITHM = "DES/ECB/PKCS5Padding";
/**
 * 轉(zhuǎn)換密鑰
 * @param key 二進(jìn)制密鑰
 * @return key 密鑰
 * @throws Exception
 */
private static Key toKey(byte[] key) throws Exception{
 //實(shí)例化DES密鑰材料
 DESKeySpec dks = new DESKeySpec(key);
 //實(shí)例化密鑰工廠
 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_ALGORITHM);
 //生產(chǎn)密鑰
 SecretKey secretKey = keyFactory.generateSecret(dks);
 return secretKey;
}
/**
 * 解密
 * @param data 待解密數(shù)據(jù)
 * @param key 密鑰
 * @return byte[] 解密數(shù)據(jù)
 * @throws Exception
 */
public static byte[] decrypt(byte[] data,byte[] key) throws Exception{
 //還原密鑰
 Key k = toKey(key);
 //實(shí)例化 
 Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
 //初始化,設(shè)置為解密模式
 cipher.init(Cipher.DECRYPT_MODE, k);
 //執(zhí)行操作
 return cipher.doFinal(data);
}
/**
 * 加密
 * @param data 待加密數(shù)據(jù)
 * @param key 密鑰
 * @return byte[] 加密數(shù)據(jù)
 * @throws Exception
 */
public static byte[] encrypt(byte[] data,byte[] key) throws Exception{
 //還原密鑰
 Key k = toKey(key);
 //實(shí)例化
 Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM,new BouncyCastleProvider());
 //初始化,設(shè)置為加密模式
 cipher.init(Cipher.ENCRYPT_MODE,k);
 //執(zhí)行操作
 return cipher.doFinal(data);
}
/**
 * 生產(chǎn)密鑰
 * java 7只支持56位 密鑰
 * Bouncy Castle 支持64位密鑰
 * @return byte[] 二進(jìn)制密鑰
 * @throws Exception
 */
public static byte[] initKey() throws Exception{
 /*
  * 實(shí)例化密鑰生成器
  * 若要使用64位密鑰注意替換
  * 講下述代碼中的
  * KeyGenerator.getInstance(KEY_ALGORITHM);
  * 替換為
  * KeyGenerator.getInstance(KEY_ALGORITHM,"BC");
  */
 KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM,new BouncyCastleProvider());

 kg.init(64);
 //生成密鑰
 SecretKey secretKey = kg.generateKey();
 //獲得密鑰的二進(jìn)制編碼形式
 return secretKey.getEncoded();
}
}

四、JavaWeb端配置

Web后端只需要在Controller中添加以下代碼,接受服務(wù)端傳遞的data和sign,并完成接收的Json字符串轉(zhuǎn)換為實(shí)體類即可

/**
 * 解密所需數(shù)據(jù)
 *
 * @param data 接受客戶端上傳的Json格式的數(shù)據(jù)
 * @param sign 接受客戶端上傳的解密數(shù)據(jù)的key值
 */
public <T> T convertJson(String data, String sign,Class<T> clazz) {
 System.out.println(data);
 System.out.println(sign);
 T tClass = null;
 try {
  //rsa加密
  RSAEncrypt rsaEncrypt = new RSAEncrypt();
  //加載rsa私鑰
  InputStream in = new FileInputStream(new File("C:\\OpenSSL-Win64\\bin\\pkcs8_rsa_private_key.pem"));
  rsaEncrypt.loadPrivateKey(in);
  //獲取RSA加密的key的數(shù)據(jù),并把該16進(jìn)制的sign轉(zhuǎn)成byte[],(客戶端采用將byte[]轉(zhuǎn)成16進(jìn)制進(jìn)行數(shù)據(jù)上傳)
  byte[] keyBytes = parseHexStr2Byte(sign);
  //通過RSA解密DES的key值
  byte[] rsaKey = rsaEncrypt.decrypt(rsaEncrypt.getPrivateKey(), keyBytes);

  //通過DES的key值解密需要的json數(shù)據(jù)
  byte[] desData = DESCoder.decrypt(parseHexStr2Byte(data), rsaKey);
  System.out.println(Arrays.toString(desData));
  System.out.println(new String(desData));
  tClass = JSON.parseObject(new String(desData), clazz);
 } catch (Exception e) {
  e.printStackTrace();
 }
 return tClass;
}


五、備注

后續(xù)會(huì)上傳相關(guān)Demo到Github

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android編程實(shí)現(xiàn)3D旋轉(zhuǎn)效果實(shí)例

    Android編程實(shí)現(xiàn)3D旋轉(zhuǎn)效果實(shí)例

    這篇文章主要介紹了Android編程實(shí)現(xiàn)3D旋轉(zhuǎn)效果的方法,基于Android的Camera類實(shí)現(xiàn)坐標(biāo)變換達(dá)到圖片3D旋轉(zhuǎn)效果,需要的朋友可以參考下
    2016-01-01
  • 解析android中ProgressBar的用法

    解析android中ProgressBar的用法

    本篇文章是對(duì)android中ProgressBar的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • Mac Android Studio安裝圖文教程

    Mac Android Studio安裝圖文教程

    本文主要介紹了Mac Android Studio安裝教程,文中通過圖文代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Android中dataBinding使用的簡(jiǎn)單封裝

    Android中dataBinding使用的簡(jiǎn)單封裝

    前面一段時(shí)間學(xué)習(xí)了一下Android中的DataBinding,但是只是很簡(jiǎn)單地實(shí)現(xiàn)了一下,DataBinding中最強(qiáng)大的地方還沒有認(rèn)真地學(xué)習(xí)過,有很多地方還不理解,下面這篇文章主要給大家介紹了關(guān)于Android中dataBinding使用的簡(jiǎn)單封裝,需要的朋友可以參考下
    2023-06-06
  • Android Drawerlayout側(cè)拉欄事件傳遞問題的解決方法

    Android Drawerlayout側(cè)拉欄事件傳遞問題的解決方法

    這篇文章主要為大家詳細(xì)介紹了Android Drawerlayout側(cè)拉欄事件傳遞問題的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • Android仿微信多人音視頻通話界面

    Android仿微信多人音視頻通話界面

    這篇文章主要為大家詳細(xì)介紹了Android仿微信多人音視頻通話界面,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • Android桌面組件App Widget完整案例

    Android桌面組件App Widget完整案例

    這篇文章主要介紹了Android桌面組件App Widget完整案例,較為詳細(xì)的分析了Android桌面組件App Widget的功能、定義及實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-09-09
  • Android動(dòng)畫效果之自定義ViewGroup添加布局動(dòng)畫(五)

    Android動(dòng)畫效果之自定義ViewGroup添加布局動(dòng)畫(五)

    這篇文章主要介紹了Android動(dòng)畫效果之自定義ViewGroup添加布局動(dòng)畫,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-08-08
  • Android動(dòng)態(tài)權(quán)限申請(qǐng)實(shí)現(xiàn)步驟分解

    Android動(dòng)態(tài)權(quán)限申請(qǐng)實(shí)現(xiàn)步驟分解

    對(duì)于一些危險(xiǎn)權(quán)限在AndroidManifest清單文件中申請(qǐng)之后,還需要得到用戶的許可并打開,才算是真正的開啟了這個(gè)權(quán)限。所以可以使用動(dòng)態(tài)申請(qǐng)權(quán)限,對(duì)于某個(gè)功能,如果需要開啟某個(gè)權(quán)限,在用戶使用它之前,彈窗提示用戶是否要開啟這個(gè)權(quán)限
    2023-04-04
  • RecyclerView焦點(diǎn)跳轉(zhuǎn)BUG優(yōu)化的方法

    RecyclerView焦點(diǎn)跳轉(zhuǎn)BUG優(yōu)化的方法

    這篇文章主要介紹了RecyclerView焦點(diǎn)跳轉(zhuǎn)BUG優(yōu)化的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧
    2018-04-04

最新評(píng)論