数字证书及加解密

当异构系统遇上 AES(Java 实现)

2017-07-04  本文已影响74人  舌尖上的大胖
image.png image.png

同理先在类中定义一个初始向量,需要与 iOS 端的统一。

private static final String IV_STRING = "16-Bytes--String";

另 Java 不需手动设置密钥大小,系统会自动根据传入的 Key 进行判断。

先引入必要的包:

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
加密方法
public static String encryptAES(String content, String key)
        throws InvalidKeyException, NoSuchAlgorithmException,
        NoSuchPaddingException, UnsupportedEncodingException,
        InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
    byte[] byteContent = content.getBytes("UTF-8");
    // 注意,为了能与 iOS 统一
    // 这里的 key 不可以使用 KeyGenerator、SecureRandom、SecretKey 生成
    byte[] enCodeFormat = key.getBytes();
    SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, "AES");
    byte[] initParam = IV_STRING.getBytes();
    IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);
    // 指定加密的算法、工作模式和填充方式
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
    byte[] encryptedBytes = cipher.doFinal(byteContent);
    // 同样对加密后数据进行 base64 编码
    Base64.Encoder encoder = Base64.getEncoder();
    return encoder.encodeToString(encryptedBytes);
}
解密方法
public static String decryptAES(String content, String key)
        throws InvalidKeyException, NoSuchAlgorithmException,
        NoSuchPaddingException, InvalidAlgorithmParameterException,
        IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
    // base64 解码
    Base64.Decoder decoder = Base64.getDecoder();
    byte[] encryptedBytes = decoder.decode(content);
    byte[] enCodeFormat = key.getBytes();
    SecretKeySpec secretKey = new SecretKeySpec(enCodeFormat, "AES");
    byte[] initParam = IV_STRING.getBytes();
    IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
    byte[] result = cipher.doFinal(encryptedBytes);
    return new String(result, "UTF-8");
}

注意以上实现的是 AES-128,因此方法传入的 key 需为长度为 16 的字符串。

关于Java使用大于128 bits的key

到 Oracle 官网下载对应 Java 版本的 JCE ,解压后放到 JAVA_HOME/jre/lib/security/ ,然后修改 iOS 端的 kKeySize 和两端对应的 key 即可。


【代码下载】

AESCipher-Java
AES4ObjC-Java-JavaScript/Java/src/

【参考资料】

AES加密 - iOS与 Java 的同步实现
AES加密 - iOS与 Java 的同步实现(转载 + 整理)

上一篇下一篇

猜你喜欢

热点阅读