RSA加密例子和中途遇到的有关问题
RSA加密例子和中途遇到的问题
在进行RSA加密例子
测试类
遇到的问题在
解密的时候 用new BASE64Encoder()).encode(keyBytes); 获得明文发现明文长度只能是4的倍数而且不支持特殊字符串和中文不然解密出来不是多出来 就是解密不对 后面解密
直接用.getBytes() 和new String(decodedData)不用Base64的就好了
在进行RSA加密例子
package test; import java.io.IOException; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; public abstract class RSACoder { public static final String KEY_ALGORITHM = "RSA"; public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; private static final String PUBLIC_KEY = "RSAPublicKey"; private static final String PRIVATE_KEY = "RSAPrivateKey"; public static byte[] decryptBASE64(String privateKey){ byte[] output = null; try { output = (new BASE64Decoder()).decodeBuffer(privateKey); return output; } catch (IOException e) { e.printStackTrace(); } return output; } public static String encryptBASE64( byte[] keyBytes){ String s = (new BASE64Encoder()).encode(keyBytes); return s; } /** * 用私钥对信息生成数字签名 * * @param data * 加密数据 * @param privateKey * 私钥 * * @return * @throws Exception */ public static String sign(byte[] data, String privateKey) throws Exception { // 解密由base64编码的私钥 byte[] keyBytes = decryptBASE64(privateKey); // 构造PKCS8EncodedKeySpec对象 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); // KEY_ALGORITHM 指定的加密算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取私钥匙对象 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); // 用私钥对信息生成数字签名 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(priKey); signature.update(data); return encryptBASE64(signature.sign()); } /** * 校验数字签名 * * @param data * 加密数据 * @param publicKey * 公钥 * @param sign * 数字签名 * * @return 校验成功返回true 失败返回false * @throws Exception * */ public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { // 解密由base64编码的公钥 byte[] keyBytes = decryptBASE64(publicKey); // 构造X509EncodedKeySpec对象 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); // KEY_ALGORITHM 指定的加密算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取公钥匙对象 PublicKey pubKey = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(pubKey); signature.update(data); // 验证签名是否正常 return signature.verify(decryptBASE64(sign)); } /** * 解密<br> * 用私钥解密 * * @param data * @param key * @return * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception { // 对密钥解密 byte[] keyBytes = decryptBASE64(key); // 取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 解密<br> * 用公钥解密 * * @param data * @param key * @return * @throws Exception */ public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception { // 对密钥解密 byte[] keyBytes = decryptBASE64(key); // 取得公钥 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicKey = keyFactory.generatePublic(x509KeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 加密<br> * 用公钥加密 * * @param data * @param key * @return * @throws Exception */ public static byte[] encryptByPublicKey(byte[] data, String key) throws Exception { // 对公钥解密 byte[] keyBytes = decryptBASE64(key); // 取得公钥 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicKey = keyFactory.generatePublic(x509KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 加密<br> * 用私钥加密 * * @param data * @param key * @return * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception { // 对密钥解密 byte[] keyBytes = decryptBASE64(key); // 取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 取得私钥 * * @param keyMap * @return * @throws Exception */ public static String getPrivateKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); return encryptBASE64(key.getEncoded()); } /** * 取得公钥 * * @param keyMap * @return * @throws Exception */ public static String getPublicKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PUBLIC_KEY); return encryptBASE64(key.getEncoded()); } /** * 初始化密钥 * * @return * @throws Exception */ public static Map<String, Object> initKey() throws Exception { KeyPairGenerator keyPairGen = KeyPairGenerator .getInstance(KEY_ALGORITHM); keyPairGen.initialize(1024); KeyPair keyPair = keyPairGen.generateKeyPair(); // 公钥 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 私钥 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); Map<String, Object> keyMap = new HashMap<String, Object>(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } }
测试类
package test; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; public class RSACoderTest { public void getKey() throws Exception { Map<String, Object> keyMap = RSACoder.initKey(); publicKey = RSACoder.getPublicKey(keyMap); privateKey = RSACoder.getPrivateKey(keyMap); System.out.println("public : "+publicKey); System.out.println("private : "+privateKey); } public static void main(String[] args) throws Exception { // System.err.println("公钥加密——私钥解密"); //将明文转换为字节数组 byte[] data = "NaUxcheADDc34m?(^%hj3&".getBytes(); //用公钥加密 byte[] encodedData = RSACoder.encryptByPublicKey(data, "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDELMnCJQgdIzzkcjcAe547dDCoGo/xB4xmhHDD" +"N/DQVwDuzLPcctv5vQjBzbIZqU8OTWXfbxqBaEpfN91ZIwqnzWJQt/Piu3I95Yce1g7+aoHgOK/k" +"8SEYV5W4Ikj3BmR2kLvb7DE2wbyWKqIhJL6Jx7PShqacghGxvCQ/qrXG9QIDAQAB"); //打印加密字符串 为什么使用BASE64Encoder 因为在RSACoder里加密用的是 BASE64Encoder 加密 String s = (new BASE64Encoder()).encode(encodedData); System.err.println("加密: " +s); //用私钥解密 byte[] decodedData = RSACoder.decryptByPrivateKey(RSACoder.decryptBASE64(s),"MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMQsycIlCB0jPORyNwB7njt0MKga" +"j/EHjGaEcMM38NBXAO7Ms9xy2/m9CMHNshmpTw5NZd9vGoFoSl833VkjCqfNYlC38+K7cj3lhx7W" +"Dv5qgeA4r+TxIRhXlbgiSPcGZHaQu9vsMTbBvJYqoiEkvonHs9KGppyCEbG8JD+qtcb1AgMBAAEC" +"gYB0pdEeYRivArn9eLCd1+OhpJgeDRVUE9H3T38hhYzqxSEn3Y6BYcbNfArN+nqRaaw5a+pMbmsL" +"UbEPZ0915jE5xBeB0PhM6sdITDSlcuXvN2nTO5u3ndEL02VvjOTwBea9luZOUCeQblu58t9E4Ust" +"16oZzYPriCeEIge85HPhAQJBAPkFc4wDRR9eIXSKml7JlPXeGCM/5/vjqaBRV/LJP6YHtnbVIQbp" +"don1q3WbFLIrxJ6gSVBQ0M+J6ay8/pmWcrUCQQDJrDPI+OZ7kM88RkYFWZeW9tcBo0lXslev/+x4" +"ptSjImy5xebZE0VwDi3IVwTFWK7soDH+bOmvlJiqXIU47WtBAkEA5nS4EWx5TOVFWuBmqrAtrjjC" +"5+Rdocx4kAiXtvWudM4Qe/sUHJx0+ookCqvhxF4jEZZPIwgXpuoAGr+xc5w7PQJACrcFgVYIGOSW" +"viMVsU8TSMgQoFuml+w30HgOflKO1aQMlso2+62UcOGv+Qb2j+2oTZYtUdFDkTqZ6eNEiMPEgQJB" +"ANAXRMqNnGHS4YYVdzcFRZ8wRUrYJYD1kCHH7IDGWFVqdQjo89OhSRdmAu6I7feFgbq+KuukSZvY" +"LtY7Xz9dkKc="); System.out.println( "解密后: " + new String(decodedData)); } }
遇到的问题在
解密的时候 用new BASE64Encoder()).encode(keyBytes); 获得明文发现明文长度只能是4的倍数而且不支持特殊字符串和中文不然解密出来不是多出来 就是解密不对 后面解密
直接用.getBytes() 和new String(decodedData)不用Base64的就好了