本文實例講述了Java編程實現非對稱加密的方法。分享給大家供大家參考,具體如下:
對稱加密算法在加密和解密時使用的是同一個秘鑰;而非對稱加密算法需要兩個密鑰來進行加密和解密,這兩個秘鑰是公開密鑰(public key,簡稱公鑰)和私有密鑰(private key,簡稱私鑰)。
是一種 高級的雙保險加密方式,一般的實現加密方式有DH密鑰交換算法,RSA基于因子分解算法,ElGamal離散對數算法及ECC橢圓曲線加密等。
DH加密解密
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
|
/** * 非對稱加密之:DH加密 * 非對稱DH,是安全性基于在有限域中計算離散對數的難度的一種加密算法。 * 可用于密鑰分發,但不能用于加/解密報文。DH即Diffie-Hellman算法的簡寫,也縮寫為D-H算法。 * D-H加密算法的核心思想就是大素數不可分解質因數的數學理論方法。 * @description: * @date 2015-10-29 上午9:08:14 */ public class EncryptDH { private static String dhStr = "encrypt test by DH" ; public static void main(String[] args) { jdkDh(); } private static void jdkDh() { try { // 初始化發送方密鑰 KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance( "DH" ); senderKeyPairGenerator.initialize( 512 ); KeyPair senderKeyPair = senderKeyPairGenerator.generateKeyPair(); byte [] senderPublicKeyEnc = senderKeyPair.getPublic().getEncoded(); // 發送方的公鑰,發送給接受方,發送方式多種,比如文件,網絡等 // 初始化接受方密鑰 KeyFactory receiverKeyFactory = KeyFactory.getInstance( "DH" ); X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(senderPublicKeyEnc); PublicKey receiverPublicKey = receiverKeyFactory.generatePublic(x509EncodedKeySpec); DHParameterSpec dhParameterSpec = ((DHPublicKey) receiverPublicKey).getParams(); KeyPairGenerator receiverKeyPairGenerator = KeyPairGenerator.getInstance( "DH" ); receiverKeyPairGenerator.initialize(dhParameterSpec); KeyPair receiveKeyPair = receiverKeyPairGenerator.generateKeyPair(); PrivateKey receiverPrivateKey = receiveKeyPair.getPrivate(); byte [] receiverPublicKeyEnc = receiveKeyPair.getPublic().getEncoded(); // 密鑰構建 KeyAgreement receiverKeyAgreement = KeyAgreement.getInstance( "DH" ); receiverKeyAgreement.init(receiverPrivateKey); receiverKeyAgreement.doPhase(receiverPublicKey, true ); SecretKey receiverSecretKey = receiverKeyAgreement.generateSecret( "DES" ); KeyFactory senderKeyFactory = KeyFactory.getInstance( "DH" ); x509EncodedKeySpec = new X509EncodedKeySpec(receiverPublicKeyEnc); PublicKey senderPublicKey = senderKeyFactory.generatePublic(x509EncodedKeySpec); KeyAgreement senderKeyAgreement = KeyAgreement.getInstance( "DH" ); senderKeyAgreement.init(senderKeyPair.getPrivate()); senderKeyAgreement.doPhase(senderPublicKey, true ); SecretKey snederSecretKey = senderKeyAgreement.generateSecret( "DES" ); if (Objects.equals(receiverSecretKey, snederSecretKey)) { System.out.println( "雙方密鑰相同" ); } // 加密 Cipher cipher = Cipher.getInstance( "DES" ); cipher.init(Cipher.ENCRYPT_MODE, snederSecretKey); byte [] result = cipher.doFinal(dhStr.getBytes()); System.out.println( "DH加密后為:" + Base64.encode(result)); // 解密 cipher.init(Cipher.DECRYPT_MODE, receiverSecretKey); result = cipher.doFinal(result); System.out.println( "DH解密后為:" + new String(result)); } catch (Exception e) { e.printStackTrace(); } } } |
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
|
/** * 非對稱加密之:RSA加密 * @description: * RSA公鑰加密算法是1977年由羅納德·李維斯特(Ron Rivest)、阿迪·薩莫爾(Adi Shamir)和倫納德·阿德曼(Leonard Adleman)一起提出的。 * 1987年首次公布,當時他們三人都在麻省理工學院工作。RSA就是他們三人姓氏開頭字母拼在一起組成的。 * RSA是目前最有影響力的公鑰加密算法,它能夠抵抗到目前為止已知的絕大多數密碼攻擊,已被ISO推薦為公鑰數據加密標準。 * 今天只有短的RSA鑰匙才可能被強力方式解破。到2008年為止,世界上還沒有任何可靠的攻擊RSA算法的方式。只要其鑰匙的長度足夠長,用RSA加密的信息實際上是不能被解破的。 * 但在分布式計算和量子計算機理論日趨成熟的今天,RSA加密安全性受到了挑戰。 * RSA算法基于一個十分簡單的數論事實:將兩個大素數相乘十分容易,但是想要對其乘積進行因式分解卻極其困難,因此可以將乘積公開作為加密密鑰。 * @date 2015-10-29 上午9:08:14 */ public class EncryptRSA { private static String rsaStr = "encrypt test by ElGamal" ; public static void main(String[] args) { jdkRSA(); } private static void jdkRSA() { try { // 初始化密鑰 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance( "RSA" ); keyPairGenerator.initialize( 512 ); KeyPair keyPair = keyPairGenerator.generateKeyPair(); RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate(); System.out.println( "RSA公鑰:" + Base64.encode(rsaPublicKey.getEncoded())); System.out.println( "RSA私鑰:" + Base64.encode(rsaPrivateKey.getEncoded())); // 私鑰加密,公鑰解密--加密 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded()); KeyFactory keyFactory = KeyFactory.getInstance( "RSA" ); PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); Cipher cipher = Cipher.getInstance( "RSA" ); cipher.init(Cipher.ENCRYPT_MODE, privateKey); byte [] result = cipher.doFinal(rsaStr.getBytes()); System.out.println( "RSA私鑰加密,公鑰解密--加密:" + Base64.encode(result)); // 私鑰加密,公鑰解密--解密 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded()); keyFactory = KeyFactory.getInstance( "RSA" ); PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); cipher = Cipher.getInstance( "RSA" ); cipher.init(Cipher.DECRYPT_MODE, publicKey); result = cipher.doFinal(result); System.out.println( "RSA私鑰加密,公鑰解密--解密:" + new String(result)); // 公鑰加密,私鑰解密--加密 x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded()); keyFactory = KeyFactory.getInstance( "RSA" ); publicKey = keyFactory.generatePublic(x509EncodedKeySpec); cipher = Cipher.getInstance( "RSA" ); cipher.init(Cipher.ENCRYPT_MODE, publicKey); result = cipher.doFinal(rsaStr.getBytes()); System.out.println( "公鑰加密,私鑰解密--加密:" + Base64.encode(result)); // 公鑰加密,私鑰解密--解密 pkcs8EncodedKeySpec= new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded()); keyFactory = KeyFactory.getInstance( "RSA" ); privateKey= keyFactory.generatePrivate(pkcs8EncodedKeySpec); cipher = Cipher.getInstance( "RSA" ); cipher.init(Cipher.DECRYPT_MODE, privateKey); result = cipher.doFinal(result); System.out.println( "公鑰加密,私鑰解密--解密:" + new String(result)); } catch (Exception e) { e.printStackTrace(); } } } |
ElGamal加密
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
|
/** * 非對稱加密之:ElGamal加密 * @description: * ElGamal算法,是一種較為常見的加密算法,它是基于1984年提出的公鑰密碼體制和橢圓曲線加密體系。 * 既能用于數據加密也能用于數字簽名,其安全性依賴于計算有限域上離散對數這一難題。 * 在加密過程中,生成的密文長度是明文的兩倍,且每次加密后都會在密文中生成一個隨機數K, * 在密碼中主要應用離散對數問題的幾個性質:求解離散對數(可能)是困難的,而其逆運算指數運算可以應用平方-乘的方法有效地計算。 * 也就是說,在適當的群G中,指數函數是單向函數。 * @date 2015-10-29 上午9:08:14 */ public class EncrypElGamal { private static String rsaStr = "encrypt test by ElGamal" ; public static void main(String[] args) { jdkRSA(); } private static void jdkRSA() { try { // 公鑰加密,私鑰解密 // Security.addProvider(new BouncyCastleProvider());//需要添加bouncycastleprovider jar //初始化密鑰 AlgorithmParameterGenerator algorithmParameterGenerator=AlgorithmParameterGenerator.getInstance( "ElGamal" ); algorithmParameterGenerator.init( 256 ); AlgorithmParameters algorithmParameters=algorithmParameterGenerator.generateParameters(); DHParameterSpec dhParameterSpec=algorithmParameters.getParameterSpec(DHParameterSpec. class ); KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance( "ElGamal" ); keyPairGenerator.initialize(dhParameterSpec, new SecureRandom()); KeyPair keyPair=keyPairGenerator.generateKeyPair(); PublicKey publicKey=keyPair.getPublic(); PrivateKey privateKey=keyPair.getPrivate(); System.out.println( "ElGamal加密公鑰:" +Base64.encode(publicKey.getEncoded())); System.out.println( "ElGamal加密私鑰:" +Base64.encode(privateKey.getEncoded())); //加密解密同Rsa是一樣的 } catch (Exception e) { e.printStackTrace(); } } } |
Ecc加密可以參考:http://www.pediy.com/kssd/pediy06/pediy6014.htm等。
希望本文所述對大家java程序設計有所幫助。
原文鏈接:http://blog.csdn.net/true100/article/details/49489137