加密算法使用(五):RSA使用全过程
RSA是一种非对称加密算法,使用RSA前先生成一对公钥和私钥。
使用公钥加密的数据可以用私钥解密,同样私钥加密的数据也可以用公钥解密,
不同之处在于,私钥加密数据的同时还可以生成一组签名,签名是用来验证数据是否在传输过程中有变动的,使用公钥、签名、以及公钥加密后的数据,就可以验证是否有变动,当然也可以不验证。
代码示例如下,两个main方法:main和main1。加密解密都是针对byte数组的,考虑到我们实际使用的时候大部分场景应该是用字符串来传递数据,所以演示代码中频繁的将byte数组转化为字符串,有些byte数组不是从字符串直接转化来的,直接通过new String的方式转字符串会出现乱码,所以用到了Base64来解决这一问题。
另外,演示代码为了方便看到全过程,基本上没有抽出方法,实际使用的时候建议重构一下。
说明就到此为止,代码如下:
1 package testEncrypt; 2 3 import java.security.Key; 4 import java.security.KeyFactory; 5 import java.security.KeyPair; 6 import java.security.KeyPairGenerator; 7 import java.security.NoSuchAlgorithmException; 8 import java.security.PrivateKey; 9 import java.security.PublicKey; 10 import java.security.Signature; 11 import java.security.interfaces.RSAPrivateKey; 12 import java.security.interfaces.RSAPublicKey; 13 import java.security.spec.InvalidKeySpecException; 14 import java.security.spec.PKCS8EncodedKeySpec; 15 import java.security.spec.X509EncodedKeySpec; 16 import java.util.HashMap; 17 import java.util.Map; 18 19 import javax.crypto.Cipher; 20 21 import org.apache.commons.codec.binary.Base64; 22 23 /** 24 * 25 * @ClassName: TestRsaEncrypt 26 * @Description: TODO 27 * @author: liuyx 28 * @date: 2016年4月28日上午10:20:59 29 */ 30 public class TestRsaEncrypt { 31 public static final String KEY_ALGORITHM = "RSA"; 32 private static final String PUBLIC_KEY = "RSAPublicKey"; 33 private static final String PRIVATE_KEY = "RSAPrivateKey"; 34 public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; 35 private static KeyFactory keyFactory = null; 36 static { 37 try { 38 keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); 39 } catch (NoSuchAlgorithmException e) { 40 // TODO Auto-generated catch block 41 e.printStackTrace(); 42 } 43 } 44 //公钥加密 私钥解密 45 public static void main(String[] args) throws Exception { 46 //生成密钥对 47 48 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); 49 keyPairGen.initialize(512); 50 51 KeyPair keyPair = keyPairGen.generateKeyPair(); 52 53 // 公钥 54 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); 55 56 // 私钥 57 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); 58 59 Map<String, Object> keyMap = new HashMap<String, Object>(2); 60 61 keyMap.put(PUBLIC_KEY, publicKey); 62 keyMap.put(PRIVATE_KEY, privateKey); 63 64 String publicKeyStr = getBase64KeyEncodeStrFromKey(publicKey); 65 String privateKeyStr = getBase64KeyEncodeStrFromKey(privateKey); 66 System.out.println("公钥:"+publicKeyStr); 67 System.out.println("私钥:"+privateKeyStr); 68 69 //数据加密过程演示 70 System.out.println("公钥加密——私钥解密"); 71 72 //要加密的数据 73 String dataStr = "abcdefghhhhhhhopqrst"; 74 System.out.println("要加密的数据:"+dataStr); 75 byte[] data = dataStr.getBytes(); 76 77 78 // 对公钥解密 79 Key decodePublicKey = getPublicKeyFromBase64KeyEncodeStr(publicKeyStr); 80 81 // 对数据加密 82 Cipher cipher = Cipher.getInstance(KEY_ALGORITHM); 83 cipher.init(Cipher.ENCRYPT_MODE, decodePublicKey); 84 byte[] encodedData = cipher.doFinal(data); 85 String encodedDataStr = Base64.encodeBase64String(encodedData); 86 System.out.println("公钥加密后的数据:"+encodedDataStr); 87 88 //对私钥解密 89 Key decodePrivateKey = getPrivateKeyFromBase64KeyEncodeStr(privateKeyStr); 90 cipher.init(Cipher.DECRYPT_MODE, decodePrivateKey); 91 encodedData = Base64.decodeBase64(encodedDataStr); 92 byte[] decodedData = cipher.doFinal(encodedData); 93 String decodedDataStr = new String(decodedData); 94 System.out.println("私钥解密后的数据:"+decodedDataStr); 95 } 96 97 //私钥加密 公钥解密,附带签名验证过程 98 public static void main1(String[] args) throws Exception { 99 //生成密钥对 100 101 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); 102 keyPairGen.initialize(512); 103 104 KeyPair keyPair = keyPairGen.generateKeyPair(); 105 106 // 公钥 107 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); 108 109 // 私钥 110 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); 111 112 Map<String, Object> keyMap = new HashMap<String, Object>(2); 113 114 keyMap.put(PUBLIC_KEY, publicKey); 115 keyMap.put(PRIVATE_KEY, privateKey); 116 117 String publicKeyStr = getBase64KeyEncodeStrFromKey(publicKey); 118 String privateKeyStr = getBase64KeyEncodeStrFromKey(privateKey); 119 System.out.println("公钥:"+publicKeyStr); 120 System.out.println("私钥:"+privateKeyStr); 121 122 //数据加密过程演示 123 System.out.println("私钥加密——公钥解密"); 124 125 //要加密的数据 126 String dataStr = "abcdefghhhhhhhopqrst1"; 127 System.out.println("要加密的数据:"+dataStr); 128 byte[] data = dataStr.getBytes(); 129 130 //对私钥解密 131 Key decodePrivateKey = getPrivateKeyFromBase64KeyEncodeStr(privateKeyStr); 132 //对公钥解密 133 Key decodePublicKey = getPublicKeyFromBase64KeyEncodeStr(publicKeyStr); 134 135 // 对数据加密 136 Cipher cipher = Cipher.getInstance(KEY_ALGORITHM); 137 cipher.init(Cipher.ENCRYPT_MODE, decodePrivateKey); 138 byte[] encodedData = cipher.doFinal(data); 139 140 //插曲,加密后的数据+私钥,生成签名,验证签名 141 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); 142 signature.initSign((PrivateKey)decodePrivateKey); //用的是私钥 143 signature.update(encodedData); //用的是加密后的数据字节数组 144 145 //取得签名 146 String sign = Base64.encodeBase64String((signature.sign())); 147 148 //初始化验证签名 149 signature = Signature.getInstance(SIGNATURE_ALGORITHM); 150 signature.initVerify((PublicKey )decodePublicKey); //用的是公钥 151 signature.update(encodedData); //用的是加密后的数据字节数组 152 153 //实际的验证过程,获取验证结果 154 boolean ret = signature.verify(Base64.decodeBase64(sign)); 155 System.out.println("验证结果:"+ret); 156 //插曲结束 157 158 159 String encodedDataStr = Base64.encodeBase64String(encodedData); 160 System.out.println("私钥加密后的数据:"+encodedDataStr); 161 162 163 164 cipher.init(Cipher.DECRYPT_MODE, decodePublicKey); 165 encodedData = Base64.decodeBase64(encodedDataStr); 166 byte[] decodedData = cipher.doFinal(encodedData); 167 String decodedDataStr = new String(decodedData); 168 System.out.println("公钥解密后的数据:"+decodedDataStr); 169 170 } 171 172 /* 173 * 获取key的base64加密后的字符串 174 */ 175 private static String getBase64KeyEncodeStrFromKey(Key key) { 176 return Base64.encodeBase64String(key.getEncoded()); 177 } 178 179 /* 180 * 获取base64加密后的字符串的原始公钥 181 */ 182 private static Key getPublicKeyFromBase64KeyEncodeStr(String keyStr) { 183 byte[] keyBytes = Base64.decodeBase64(keyStr); 184 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); 185 Key publicKey = null; 186 try { 187 publicKey = keyFactory.generatePublic(x509KeySpec); 188 } catch (Exception e) { 189 // TODO Auto-generated catch block 190 e.printStackTrace(); 191 } 192 return publicKey; 193 } 194 195 private static Key getPrivateKeyFromBase64KeyEncodeStr(String keyStr) { 196 byte[] keyBytes = Base64.decodeBase64(keyStr); 197 // 取得私钥 198 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); 199 200 Key privateKey=null; 201 try { 202 privateKey = keyFactory.generatePrivate(pkcs8KeySpec); 203 } catch (InvalidKeySpecException e) { 204 // TODO Auto-generated catch block 205 e.printStackTrace(); 206 } 207 return privateKey; 208 } 209 }