前言:
RSA是第一個(gè)比較完善的公開密鑰算法,它既能用于加密,也能用于數(shù)字簽名。RSA以它的三個(gè)發(fā)明者Ron Rivest, Adi Shamir, Leonard Adleman的名字首字母命名,這個(gè)算法經(jīng)受住了多年深入的密碼分析,雖然密碼分析者既不能證明也不能否定RSA的安全性,但這恰恰說明該算法有一定的可信性,目前它已經(jīng)成為最流行的公開密鑰算法。
RSA的安全基于大數(shù)分解的難度。其公鑰和私鑰是一對(duì)大素?cái)?shù)(100到200位十進(jìn)制數(shù)或更大)的函數(shù)。從一個(gè)公鑰和密文恢復(fù)出明文的難度,等價(jià)于分解兩個(gè)大素?cái)?shù)之積(這是公認(rèn)的數(shù)學(xué)難題)。
RSA加密與解密
RSA算法的密鑰由公鑰和私鑰組成,公鑰用于加密,私鑰用于解密。顧名思義,公鑰就是可以進(jìn)行公開的密鑰,一般可以公開給你的合作伙伴;私鑰就是私有的,也就是只有你知道的,你的合作伙伴通過你提供的公鑰進(jìn)行加密的內(nèi)容只有你能進(jìn)行解密,這樣也就只有你知道他發(fā)的是什么內(nèi)容。用于加密的公鑰和私鑰是配對(duì)的。這樣的一對(duì)密鑰在Java中由
java.security.KeyPairGenerator來產(chǎn)生。以下是一個(gè)生成密鑰對(duì)的示例,該示例中還將生成的密鑰對(duì)分別保存到了文件中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
private static final String ALGORITHM = "RSA" ; private static final String PRIVATE_KEY_PATH = "D:\\rsa_private.isa" ; private static final String PUBLIC_KEY_PATH = "D:\\rsa_public.isa" ; /** * 生成公鑰和私鑰并存儲(chǔ)到文件中 * @throws Exception */ @Test public void geneKeyPair() throws Exception { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM); keyPairGenerator.initialize( 1024 ); KeyPair keyPair = keyPairGenerator.generateKeyPair(); PrivateKey privateKey = keyPair.getPrivate(); //私鑰 PublicKey publicKey = keyPair.getPublic(); //公鑰 byte [] privateKeyBytes = privateKey.getEncoded(); //私鑰對(duì)應(yīng)的字節(jié)數(shù)組 byte [] publicKeyBytes = publicKey.getEncoded(); //公鑰對(duì)應(yīng)的字節(jié)數(shù)組 Files.write(Paths.get(PRIVATE_KEY_PATH), privateKeyBytes); Files.write(Paths.get(PUBLIC_KEY_PATH), publicKeyBytes); } |
加密
加密的過程跟使用AES算法進(jìn)行加密的過程類似,唯一需要注意的是使用存儲(chǔ)起來的公鑰時(shí)需要使用X509EncodedKeySpec進(jìn)行封裝,然后通過KeyFactory.generatePublic(KeySpec)進(jìn)行生成。
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
|
@Test public void testEncrypt() throws Exception { this .encrypt( "Hello RSA" ); } /** * 公鑰加密 * @param value * @return * @throws Exception */ private byte [] encrypt(String value) throws Exception { Cipher cipher = Cipher.getInstance(ALGORITHM); //讀取公鑰對(duì)應(yīng)的字節(jié)數(shù)組 byte [] publicKeyCode = Files.readAllBytes(Paths.get(PUBLIC_KEY_PATH)); //構(gòu)造公鑰,存儲(chǔ)起來的公鑰需要使用X509EncodedKeySpec進(jìn)行讀取 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyCode); KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); //根據(jù)已有的KeySpec生成對(duì)應(yīng)的公鑰 PublicKey publicKey = keyFactory.generatePublic(keySpec); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte [] result = cipher.doFinal(value.getBytes()); System.out.println(Base64.getEncoder().encodeToString(result)); return result; } |
解密
解密是使用的密鑰對(duì)中的私鑰,其使用方法跟AES算法進(jìn)行解密類似。 存儲(chǔ)起來的私鑰需要通過PKCS8EncodedKeySpec加載,然后通過KeyFactory.generatePrivate(KeySpec)生成私鑰。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
/** * 私鑰解密 * @throws Exception */ @Test public void testDecrypt() throws Exception { Cipher cipher = Cipher.getInstance(ALGORITHM); byte [] privateKeyCode = Files.readAllBytes(Paths.get(PRIVATE_KEY_PATH)); //私鑰需要通過PKCS8EncodedKeySpec來讀取 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyCode); KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM); //生成私鑰 PrivateKey privateKey = keyFactory.generatePrivate(keySpec); cipher.init(Cipher.DECRYPT_MODE, privateKey); String content = "Java Program" ; byte [] input = this .encrypt( "Java Program" ); byte [] result = cipher.doFinal(input); Assert.assertTrue(content.equals( new String(result))); } |
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
原文鏈接:http://blog.csdn.net/u014693253/article/details/72817873