Java加密体系JCA
Java抽象了一套密码算法框架JCA(Java Cryptography Architecture),在此框架中定义了一套接口与类,以规范Java平台密码算法的实现,而Sun,SunRsaSign,SunJCE这些则是一个个JCA的实现Provider,以实现具体的密码算法,这有点像List与ArrayList、LinkedList的关系一样,Java开发者只需要使用JCA即可,而不用管具体是怎么实现的。
JCA里定义了一系列类,如Cipher、MessageDigest、MAC、Signature等,分别用于实现加密、密码学哈希、认证码、数字签名等算法,一起来看看吧!
对称加密
对称加密算法,使用Cipher类即可,以广泛使用的AES为例,如下:
public byte[] encrypt(byte[] data, Key key) {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] iv = SecureRandoms.randBytes(cipher.getBlockSize());
//初始化密钥与加密参数iv
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
//加密
byte[] encryptBytes = cipher.doFinal(data);
//将iv与密文拼在一起
ByteArrayOutputStream baos = new ByteArrayOutputStream(iv.length + encryptBytes.length);
baos.write(iv);
baos.write(encryptBytes);
return baos.toByteArray();
} catch (Exception e) {
return ExceptionUtils.rethrow(e);
}
}
public byte[] decrypt(byte[] data, Key key) {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
//获取密文前面的iv
IvParameterSpec ivSpec = new IvParameterSpec(data, 0, cipher.getBlockSize());
cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
//解密iv后面的密文
return cipher.doFinal(data, cipher.getBlockSize(), data.length - cipher.getBlockSize());
} catch (Exception e) {
return ExceptionUtils.rethrow(e);
}
}
如上,对称加密主要使用Cipher,不管是AES还是DES,Cipher.getInstance()传入不同的算法名称即可,这里的Key参数就是加密时使用的密钥,稍后会介绍它是怎么来的,暂时先忽略它。
另外,为了使得每次加密出来的密文不同,我使用了随机的iv向量,并将iv向量拼接在了密文前面。
注:如果某个算法名称,如上面的
AES/CBC/PKCS5Padding,你不知道它在JCA中的标准名称是什么,可以到 docs.oracle.com/en/java/jav… 中查询即可。
非对称加密
非对称加密同样是使用Cipher类,只是传入的密钥对象不同,以RSA算法为例,如下:
public byte[] encryptByPublicKey(byte[] data, PublicKey publicKey){
try{
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
}catch (Exception e) {
throw Errors.toRuntimeException(e);
}
}
public byte[] decryptByPrivateKey(byte[] data, PrivateKey privateKey){
try{
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}catch (Exception e) {
throw Errors.toRuntimeException(e);
}
}
一般来说应使用公钥加密,私钥解密,但其实反过来也是可以的,这里的PublicKey与PrivateKey也先忽略,后面会介绍它怎么来的。
密码学哈希
密码学哈希算法包括MD5、SHA1、SHA256等,在JCA中都使用MessageDigest类即可,如下:
public static String sha256(byte[] bytes) throws NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(bytes);
return Hex.encodeHexString(digest.digest());
}
消息认证码
消息认证码使用Mac类实现,以常见的HMAC搭配SHA256为例,如下:
public byte[] digest(byte[] data, Key key) throws InvalidKeyException, NoSuchAlgorithmException{
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(key);
return mac.doFinal(data);
}
数字签名
数字签名使用Signature类实现,以RSA搭配SHA256为例,如下:
public byte[] sign(byte[] data, PrivateKey privateKey) {
try {
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
signature.update(data);
return signature.sign();
} catch (Exception e) {
return ExceptionUtils.rethrow(e);
}
}
public boolean verify(byte[] data, PublicKey publicKey, byte[] sign) {
try {
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initVerify(publicKey);
signature.update(data);
return signature.verify(sign);
} catch (Exception e) {
return ExceptionUtils.rethrow(e);
}
}
密钥协商算法
在JCA中,使用KeyAgreement来调用密钥协商算法,以ECDH协商算法为例,如下:
public static void testEcdh() {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp256r1");
keyGen.initialize(ecSpec);
// A生成自己的私密信息
KeyPair keyPairA = keyGen.generateKeyPair();
KeyAgreement kaA = KeyAgreement.getInstance("ECDH");
kaA.init(keyPairA.getPrivate());
// B生成自己的私密信息
KeyPair keyPairB = keyGen.generateKeyPair();
KeyAgreement kaB = KeyAgreement.getInstance("ECDH");
kaB.init(keyPairB.getPrivate());
// B收到A发送过来的公用信息,计算出对称密钥
kaB.doPhase(keyPairA.getPublic(), true);
byte[] kBA = kaB.generateSecret();
// A收到B发送过来的公开信

本文详细介绍了Java Cryptography Architecture(JCA)框架下的密码算法,包括对称加密(如AES)、非对称加密(如RSA)、密码学哈希、消息认证码、数字签名、密钥协商算法以及基于口令加密PBE。通过Cipher、MessageDigest、MAC、Signature等类展示了具体实现,并讲解了密钥生成、读取、证书生成与读取的相关知识,如SecureRandom、KeyGenerator、KeyPairGenerator、KeyFactory等。文章还涵盖了常见的问题,如密文解密失败、签名验证失败和证书信任问题,提供了解决方案。
最低0.47元/天 解锁文章
52

被折叠的 条评论
为什么被折叠?



