RSA加密技术:
这种加密算法的特点主要是密钥的变化,上文我们看到DES只有一个密钥。相当于只有一把钥匙,如果这把钥匙丢了,数据也就不安全了。RSA同时有两把钥匙,公钥与私钥。同时支持数字签名。数字签名的意义在于,对传输过来的数据进行校验。确保数据在传输工程中不被修改。
流程分析:
- 甲方构建密钥对儿,将公钥公布给乙方,将私钥保留。
- 甲方使用私钥加密数据,然后用私钥对加密后的数据签名,发送给乙方签名以及加密后的数据;乙方使用公钥、签名来验证待解密数据是否有效,如果有效使用公钥对数据解密。
- 乙方使用公钥加密数据,向甲方发送经过加密后的数据;甲方获得加密数据,通过私钥解密。
按如上步骤给出序列图,如下:
对应java代码如下:
public class RSACipher
{
/**
* 公钥加密
*
* @param rawText 原文
* @param public_key 公钥
* @param encoding 编码格式
* @return 加密后的密文
* @throws Exception
*/
public static String encrypt(String rawText, String public_key, String encoding) throws Exception
{
PublicKey pubkey = getPublicKey(public_key);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubkey);
return Base64.encode(cipher.doFinal(rawText.getBytes(encoding)));
}
/**
* 私钥解密
*
* @param cipherText 密文
* @param private_key 信任的客户端私钥
* @param encoding 编码格式
* @return 解密后的字符串
*/
public static String decrypt(String cipherText, String private_key, String encoding) throws Exception
{
PrivateKey prikey = getPrivateKey(private_key);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, prikey);
return new String(cipher.doFinal(Base64.decode(cipherText)), encoding);
}
/**
* 获得公钥
*
* @param public_key
* @return
* @throws Exception
*/
private static PublicKey getPublicKey(String public_key) throws Exception
{
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] encodedKey = Base64.decode(public_key);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey);
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}
/**
* 获得私钥
*
* @param key 密钥字符串(经过base64编码)
* @throws Exception
*/
public static PrivateKey getPrivateKey(String key) throws Exception
{
byte[] keyBytes;
keyBytes = Base64.decode(key);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
}
再写一个测试类:
public class TestRSACoder {
private String publicKey;
private String privateKey;
@Before
public void testInitKey() throws Exception
{
Map<String, Object> keyMap = RSACoder.initKey();
publicKey = RSACoder.getPublicKey(keyMap);
privateKey = RSACoder.getPrivateKey(keyMap);
System.out.println("公钥: \n\r" + publicKey);
System.out.println("私钥: \n\r" + privateKey);
}
@Test
public void testEncryptDecrypt() throws Exception
{
String givenText = "testData";
System.out.println("加密前数据 :"+givenText);
String cipherText = RSACipher.encrypt(givenText, publicKey, "utf-8");
String rawText = RSACipher.decrypt(cipherText, privateKey, "utf-8");
System.out.println("解密后数据 :"+rawText);
assertEquals(givenText, rawText);
}
}