敏感信息加解密
<h2>敏感信息加解密</h2>
<p>为了保证通信过程中敏感信息字段(如用户密码、手机号码等)的机密性,平台要求应用对上送的敏感信息字段进行加密。与之相对应,平台会对下行的敏感信息字段进行加密,应用需解密后方能得到原文。下面详细介绍加解密的方式,以及如何进行相应的计算。</p>
<h3>加密算法</h3>
<p>敏感信息加密使用[AES加密算法]。</p>
<p>开发者应当使用平台给应用分配的<em>加密秘钥</em>,对上送的敏感信息进行加密。这样只有拥有秘钥的请求才能对密文进行解密,从而保证了信息的机密性。</p>
<p>另一方面,平台使用加密秘钥对下行的敏感信息进行加密。开发者应使用_加密秘钥_对下行的敏感信息的密文进行解密。</p>
<h3>加解密示例</h3>
<pre><code>import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
/**
* AES 加密
*/
@Slf4j
public class AesEncryptUtil {
/**
* AES加密
*
* @param content
* @return
*/
public static String encrypt(String content, String encryptKey) {
try {
//生成和mysql一直的加密数据
SecretKeySpec key = generateAesKey(encryptKey, StandardCharsets.UTF_8);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cleartext = content.getBytes(StandardCharsets.UTF_8);
byte[] ciphertextBytes = cipher.doFinal(cleartext);
return Hex.encodeHexString(ciphertextBytes).toUpperCase();
} catch (NoSuchAlgorithmException e) {
log.error("AesEncryptUtil.encrypt 加密失败, content={}", content, e);
} catch (NoSuchPaddingException e) {
log.error("AesEncryptUtil.encrypt 加密失败, content={}", content, e);
} catch (InvalidKeyException e) {
log.error("AesEncryptUtil.encrypt 加密失败, content={}", content, e);
} catch (IllegalBlockSizeException e) {
log.error("AesEncryptUtil.encrypt 加密失败, content={}", content, e);
} catch (BadPaddingException e) {
log.error("AesEncryptUtil.encrypt 加密失败, content={}", content, e);
} catch (Exception e) {
log.error("AesEncryptUtil.encrypt 加密异常, content={}", content, e);
}
return null;
}
/**
* AES解密
*
* @param content
* @return
*/
public static String decrypt(String content, String encryptKey) {
try {
SecretKey key = generateAesKey(encryptKey, StandardCharsets.UTF_8);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] cleartext = Hex.decodeHex(content.toCharArray());
byte[] ciphertextBytes = cipher.doFinal(cleartext);
return new String(ciphertextBytes, StandardCharsets.UTF_8);
} catch (NoSuchAlgorithmException e) {
log.error("AesEncryptUtil.decrypt 解密失败, content={}", content, e);
} catch (NoSuchPaddingException e) {
log.error("AesEncryptUtil.decrypt 解密失败, content={}", content, e);
} catch (InvalidKeyException e) {
log.error("AesEncryptUtil.decrypt 解密失败, content={}", content, e);
} catch (IllegalBlockSizeException e) {
log.error("AesEncryptUtil.decrypt 解密失败, content={}", content, e);
} catch (BadPaddingException e) {
log.error("AesEncryptUtil.decrypt 解密失败, content={}", content, e);
} catch (DecoderException e) {
log.error("AesEncryptUtil.decrypt 解密失败, content={}", content, e);
} catch (Exception e) {
log.error("AesEncryptUtil.decrypt 解密异常, content={}", content, e);
}
return null;
}
public static SecretKeySpec generateAesKey(final String key, Charset encoding) {
final byte[] finalKey = new byte[16];
int i = 0;
for (byte b : key.getBytes(encoding))
finalKey[i++ % 16] ^= b;
return new SecretKeySpec(finalKey, "AES");
}
/**
* 测试
*/
public static void main(String[] args) {
String text = "MyPassword123@163.com";
String key = "13E80F176EDCA604";
String encryptStr = encrypt(text, key);
System.out.println("数据:" + text);
System.out.println("加密:" + encryptStr);
String decryptStr = decrypt(encryptStr, key);
System.out.println("解密:" + decryptStr + "----->匹配结果=" + (decryptStr.equals(text)));
}
}</code></pre>