RSA 加密解密算法 Java 实现 http://my.oschina.net/bairrfhoinn/blog/735054
RSA公钥加密,私钥解密
这是最常用到的模式。为什么这么使用,因为在RSA的密钥分配中,你是将私钥自己保留着,而将公钥公开。私钥具有唯一性,只有自己知道。公钥是广泛分布的,可以认为大家都知道的。
当你想让其他人给你发送一条加密数据的时候,你首先把公钥给他,他用公钥加密数据,并把公钥加密后的数据发送给你。你这就可以用私钥来解密了。而如果其他人拿到他发送的数据,是没有办法解密的,因为私钥只在你手中。
这就保证了数据不会被外人解析。
RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要壹对密钥,使用其中壹個加密,则需要用另壹個才能解密。
代码一:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
import javax.crypto.Cipher; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.security.Key; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; public class RSAUtil { //指定加密算法为RSA private static String ALGORITHM = "RSA"; //指定key的大小 private static int KEYSIZE = 1024; //指定公钥存放文件和私钥存放文件 private static String PUBLIC_KEY_FILE = "src/public.key"; private static String PRIVATE_KEY_FILE = "src/private.key"; //生成公钥和私钥并分别存放在文件中 private static void generateKeyPair() throws Exception{ //生成密钥对 KeyPairGenerator kpg = KeyPairGenerator.getInstance(ALGORITHM); kpg.initialize(KEYSIZE, new SecureRandom()); KeyPair kp = kpg.generateKeyPair(); //通过密钥对分别得到公钥和私钥 Key publicKey = kp.getPublic(); Key privateKey = kp.getPrivate(); //将生成的密钥写入文件 ObjectOutputStream output1 = new ObjectOutputStream(new FileOutputStream(PUBLIC_KEY_FILE)); ObjectOutputStream output2 = new ObjectOutputStream(new FileOutputStream(PRIVATE_KEY_FILE)); output1.writeObject(publicKey); output2.writeObject(privateKey); output1.close(); output2.close(); } //RSA加密方法 public static String encrypt(String source, String publicKeyFile) throws Exception { //读出文件中的公钥对象 ObjectInputStream ois = new ObjectInputStream(new FileInputStream(publicKeyFile)); Key key = (Key) ois.readObject(); ois.close(); //得到Cipher对象来实现对源数据的RSA加密 Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, key); BASE64Encoder encoder = new BASE64Encoder(); byte[] b = source.getBytes(); String cryptograph = encoder.encode(cipher.doFinal(b)); return cryptograph; } //RSA解密方法 public static String decrypt(String cryptograph, String privateKeyFile) throws Exception { //读出文件中的私钥对象 ObjectInputStream input = new ObjectInputStream(new FileInputStream(privateKeyFile)); Key key = (Key) input.readObject(); input.close(); //对已经加密的数据进行RSA解密 Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, key); BASE64Decoder decoder = new BASE64Decoder(); byte[] b1 = decoder.decodeBuffer(cryptograph); //执行解密操作 byte[] b = cipher.doFinal(b1); String source = new String(b); return source; } //调用方法举例 public static void main(String[] args) { String source = "黑客帝国三部曲"; System.out.println("明文字符串:[" + source + "]"); try{ //生成可用的密钥对并分别保存在文件中 generateKeyPair(); System.out.println("生成的公钥文件为:" + PUBLIC_KEY_FILE + ", 生成的私钥文件为:" + PRIVATE_KEY_FILE); String cryptograph = encrypt(source, PUBLIC_KEY_FILE);//生成的密文 System.out.println("加密之后的字符串为:[" + cryptograph + "]"); String text = decrypt(cryptograph, PRIVATE_KEY_FILE);//解密密文 System.out.println("解密之后的字符串为:[" + text + "]"); }catch(Exception e){ System.out.println("加解密过程中发生错误:" + e.getMessage()); return; } } } |
运行之后的输出结果如下:
1 2 3 4 5 6 |
明文字符串:[黑客帝国三部曲] 生成的公钥文件为:src/public.key, 生成的私钥文件为:src/private.key 加密之后的字符串为:[DchhknQJfF22X6OSR+zT/TJCWiIGq8sqcYufBiP587kwIeGQdrzYDFH0PkIqZTfgj58ph2NxpCKy HbisTwAXYlLdWna3xxfn+4wblkGOFcvoMB/yR6brTnr1B2bT1pE7zJIydsijM+izeIOm8yjXQh9d Ayw0KLQP6qGLd8B/x/E=] 解密之后的字符串为:[黑客帝国三部曲] |
代码而:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 |
package xyz.ss945.s.han.common.utils; import org.apache.commons.codec.binary.Base64; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.math.BigInteger; 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.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.RSAPublicKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; public class RSAUtils { private static String RSA = "RSA"; /** * 随机生成RSA密钥对(默认密钥长度为1024) * * @return */ public static KeyPair generateRSAKeyPair() { return generateRSAKeyPair(1024); } /** * 随机生成RSA密钥对 * * @param keyLength 密钥长度,范围:512~2048<br> 一般1024 * @return */ public static KeyPair generateRSAKeyPair(int keyLength) { try { KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA); kpg.initialize(keyLength); return kpg.genKeyPair(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } } /** * 用公钥加密 <br> * 每次加密的字节数,不能超过密钥的长度值减去11 * * @param data 需加密数据的byte数据 * @param publicKey 公钥 * @return 加密后的byte型数据 */ public static byte[] encryptData(byte[] data, PublicKey publicKey) { try { Cipher cipher = Cipher.getInstance(RSA); // 编码前设定编码方式及密钥 cipher.init(Cipher.ENCRYPT_MODE, publicKey); // 传入编码数据并返回编码结果 return cipher.doFinal(data); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 用私钥解密 * * @param encryptedData 经过encryptedData()加密返回的byte数据 * @param privateKey 私钥 * @return */ public static byte[] decryptData(byte[] encryptedData, PrivateKey privateKey) { try { Cipher cipher = Cipher.getInstance(RSA); cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(encryptedData); } catch (Exception e) { return null; } } /** * 通过公钥byte[](publicKey.getEncoded())将公钥还原,适用于RSA算法 * * @param keyBytes * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException */ public static PublicKey getPublicKey(byte[] keyBytes) throws NoSuchAlgorithmException, InvalidKeySpecException { X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(RSA); PublicKey publicKey = keyFactory.generatePublic(keySpec); return publicKey; } /** * 通过私钥byte[]将公钥还原,适用于RSA算法 * * @param keyBytes * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException */ public static PrivateKey getPrivateKey(byte[] keyBytes) throws NoSuchAlgorithmException, InvalidKeySpecException { PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(RSA); PrivateKey privateKey = keyFactory.generatePrivate(keySpec); return privateKey; } /** * 使用N、e值还原公钥 * * @param modulus * @param publicExponent * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException */ public static PublicKey getPublicKey(String modulus, String publicExponent) throws NoSuchAlgorithmException, InvalidKeySpecException { BigInteger bigIntModulus = new BigInteger(modulus); BigInteger bigIntPrivateExponent = new BigInteger(publicExponent); RSAPublicKeySpec keySpec = new RSAPublicKeySpec(bigIntModulus, bigIntPrivateExponent); KeyFactory keyFactory = KeyFactory.getInstance(RSA); PublicKey publicKey = keyFactory.generatePublic(keySpec); return publicKey; } /** * 使用N、d值还原私钥 * * @param modulus * @param privateExponent * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException */ public static PrivateKey getPrivateKey(String modulus, String privateExponent) throws NoSuchAlgorithmException, InvalidKeySpecException { BigInteger bigIntModulus = new BigInteger(modulus); BigInteger bigIntPrivateExponent = new BigInteger(privateExponent); RSAPublicKeySpec keySpec = new RSAPublicKeySpec(bigIntModulus, bigIntPrivateExponent); KeyFactory keyFactory = KeyFactory.getInstance(RSA); PrivateKey privateKey = keyFactory.generatePrivate(keySpec); return privateKey; } /** * 从字符串中加载公钥 * * @param publicKeyStr 公钥数据字符串 * @throws Exception 加载公钥时产生的异常 */ public static RSAPublicKey loadPublicKey(String publicKeyStr) throws Exception { try { byte[] buffer = new Base64().decode(publicKeyStr); KeyFactory keyFactory = KeyFactory.getInstance(RSA); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer); return (RSAPublicKey) keyFactory.generatePublic(keySpec); } catch (NoSuchAlgorithmException e) { throw new Exception("无此算法"); } catch (InvalidKeySpecException e) { throw new Exception("公钥非法"); } catch (NullPointerException e) { throw new Exception("公钥数据为空"); } } /** * 从字符串中加载私钥<br> * 加载时使用的是PKCS8EncodedKeySpec(PKCS#8编码的Key指令)。 * * @param privateKeyStr * @return * @throws Exception */ public static RSAPrivateKey loadPrivateKey(String privateKeyStr) throws Exception { try { byte[] buffer = new Base64().decode(privateKeyStr); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer); KeyFactory keyFactory = KeyFactory.getInstance(RSA); return (RSAPrivateKey) keyFactory.generatePrivate(keySpec); } catch (NoSuchAlgorithmException e) { throw new Exception("无此算法"); } catch (InvalidKeySpecException e) { throw new Exception("私钥非法"); } catch (NullPointerException e) { throw new Exception("私钥数据为空"); } } /** * 从文件中输入流中加载公钥 * * @param in 公钥输入流 * @throws Exception 加载公钥时产生的异常 */ public static PublicKey loadPublicKey(InputStream in) throws Exception { try { return loadPublicKey(readKey(in)); } catch (IOException e) { throw new Exception("公钥数据流读取错误"); } catch (NullPointerException e) { throw new Exception("公钥输入流为空"); } } /** * 从文件中加载私钥 * * @param in 证书文件流 * @return rsa私钥证书 * @throws Exception */ public static RSAPrivateKey loadPrivateKey(InputStream in) throws Exception { try { return loadPrivateKey(readKey(in)); } catch (IOException e) { throw new Exception("私钥数据读取错误"); } catch (NullPointerException e) { throw new Exception("私钥输入流为空"); } } /** * 读取密钥信息 * * @param in * @return * @throws IOException */ private static String readKey(InputStream in) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(in)); String readLine = null; StringBuilder sb = new StringBuilder(); while ((readLine = br.readLine()) != null) { if (readLine.charAt(0) == '-') { continue; } else { sb.append(readLine); sb.append('\r'); } } return sb.toString(); } } |