java rsa加密解密

来源:互联网 发布:卫生间js防水技术交底 编辑:程序博客网 时间:2024/05/29 12:54

rsa加密:公钥加密,私钥解密。

首先,我们先要生成密钥对:

public static void createRSAKey(String privateKeyPath, String publicKeyPath) throws BasicException {KeyPairGenerator kpg = null;try {kpg = KeyPairGenerator.getInstance("RSA");} catch (NoSuchAlgorithmException e) {throw new RsaException(e);}kpg.initialize(1024); // 指定密钥长度KeyPair kp = kpg.genKeyPair(); // 生成密钥对PublicKey public_key = kp.getPublic(); // 获得公钥PrivateKey private_key = kp.getPrivate(); // 获得私钥String publicKeyStr = Base64.encodeBase64String(public_key.getEncoded());// 创建公钥FileUtil.createFile(publicKeyPath, publicKeyStr.getBytes());String privateKeyStr = Base64.encodeBase64String(private_key.getEncoded());// 创建私钥FileUtil.createFile(privateKeyPath, privateKeyStr.getBytes());}
需要注意的是,密钥的长度是跟加密后的密文长度有关。当密钥长度加倍时,rsa解密密文的最大值也要加倍。

然后,我们就要对明文进行加密解密了。但是rsa对加密明文的长度是有限制的,最大长度为117字节,否则就会抛出异常:

Data must not be longer than 117 bytes

所以我们要采用分段加密的方式:

// rsa最大加密明文大小private static final int MAX_ENCRYPT_BLOCK = 117;// rsa最大解密密文大小private static final int MAX_DECRYPT_BLOCK = 128;// 分段加密private static String encryptByKey(String data, Key key) throws BasicException {Cipher cipher;try {cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, key);} catch (Exception e) {throw new RsaException(e);} int length = data.length();int offset = 0;byte[] result = null;int i = 0;while (length - offset > 0) {byte[] cache;try {if (length - offset > MAX_ENCRYPT_BLOCK) {cache = cipher.doFinal(data.getBytes(), offset, MAX_ENCRYPT_BLOCK);} else {cache = cipher.doFinal(data.getBytes(), offset, length - offset);}} catch (Exception e) {throw new RsaException(e);}result = VDILicenseCreator.concat(result, cache);i++;offset = i * MAX_ENCRYPT_BLOCK;}return Base64.encodeBase64String(result);}// 分段解密private static String decryptByKey(String data, Key key) throws BasicException {Cipher cipher;try {cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, key);} catch (Exception e) {throw new RsaException(e);}byte[] data64 = Base64.decodeBase64(data);int length = data64.length;int offset = 0;byte[] result = null;int i = 0;while (length - offset > 0) {byte[] cache;try {if (length - offset > MAX_DECRYPT_BLOCK) {cache = cipher.doFinal(data64, offset, MAX_DECRYPT_BLOCK);} else {cache = cipher.doFinal(data64, offset, length - offset);}} catch (Exception e) {throw new RsaException(e);}result = VDILicenseCreator.concat(result, cache);i++;offset = i * MAX_DECRYPT_BLOCK;}return new String(result);}

上面的代码中,还有一个rsa最大解密密文大小。加密分段,解密当然也要分段了。当密钥的长度为1024时,小于117字节的明文,加密后长度都是128字节(所以分段加密后,密文的长度都是128的整数倍),所以上面rsa最大解密密文大小设置为128。但是,如果密钥的长度为2048时,这个值就要随之翻倍,设置为256。如果仍设置为128,则会抛出异常:

Data must start with zero

下面备注了我们所用到的jar包:

import java.security.Key;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.NoSuchAlgorithmException;import java.security.PrivateKey;import java.security.PublicKey;import java.security.SecureRandom;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import javax.crypto.Cipher;import org.apache.commons.codec.binary.Base64;



0 0