分享

JAVA使用openssl生成的公私钥做加密解密 | PHPor 的Blog

 WindySky 2016-07-04

使用openssl生成密钥对:

1
2
3
4
5
6
>openssl genrsa -out private.key
>openssl rsa -in private.key -pubout -outform PEM -out public.key
// 因为java里面不识别x509格式的私钥,所以必须转换为 pkcs8格式方可使用
// java异常描述为: java.security.spec.InvalidKeySpecException: Only RSAPrivate(Crt)KeySpec and PKCS8EncodedKeySpec supported for RSA private keys
// 虽然RSAPrivate(Crt)KeySpec 也支持,但是目前还不知道怎么用
>openssl pkcs8 -topk8 -inform PEM -outform PEM -in private.key -out pkcs8_priv.pem -nocrypt

 

java代码:

1. 注意: java 语言本身没有实现base64编码,而openssl生成的密钥对一般做base64编码,便于维护,所以这里引用了 org.apache.commons.codec.binary.Base64;

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
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import javax.crypto.Cipher;
import org.apache.commons.codec.binary.Base64;
//下载地址: http://commons./codec/download_codec.cgi
public static class MyRsa {
/**
* String to hold name of the encryption algorithm.
*/
public static final String ALGORITHM = "RSA";
/**
* String to hold the name of the private key file.
*/
public static final String PRIVATE_KEY_FILE = "D:/rsa/pkcs8_priv.pem";
/**
* String to hold name of the public key file.
*/
public static final String PUBLIC_KEY_FILE = "D:/rsa/public.key";
/**
* Encrypt the plain text using public key.
*
* @param text
*            : original plain text
* @param key
*            :The public key
* @return Encrypted text
* @throws java.lang.Exception
*/
public static byte[] encrypt(String text, PublicKey key) {
byte[] cipherText = null;
try {
// get an RSA cipher object and print the provider
final Cipher cipher = Cipher.getInstance(ALGORITHM);
// encrypt the plain text using the public key
cipher.init(Cipher.ENCRYPT_MODE, key);
cipherText = cipher.doFinal(text.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
return cipherText;
}
/**
* Decrypt text using private key.
*
* @param text
*            :encrypted text
* @param key
*            :The private key
* @return plain text
* @throws java.lang.Exception
*/
public static String decrypt(byte[] text, PrivateKey key) {
byte[] dectyptedText = null;
try {
// get an RSA cipher object and print the provider
final Cipher cipher = Cipher.getInstance(ALGORITHM);
// decrypt the text using the private key
cipher.init(Cipher.DECRYPT_MODE, key);
dectyptedText = cipher.doFinal(text);
} catch (Exception ex) {
ex.printStackTrace();
}
return new String(dectyptedText);
}
public static void test() {
String s = "Hello world";
try {
BufferedReader privateKey = new BufferedReader(new FileReader(
PRIVATE_KEY_FILE));
BufferedReader publicKey = new BufferedReader(new FileReader(
PUBLIC_KEY_FILE));
String strPrivateKey = "";
String strPublicKey = "";
String line = "";
while((line = privateKey.readLine()) != null){
strPrivateKey += line;
}
while((line = publicKey.readLine()) != null){
strPublicKey += line;
}
privateKey.close();
publicKey.close();
// 私钥需要使用pkcs8格式的,公钥使用x509格式的
String strPrivKey = strPrivateKey.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "");
String strPubKey = strPublicKey.replace("-----BEGIN PUBLIC KEY-----", "")
.replace("-----END PUBLIC KEY-----", "");
//System.out.print(strPrivKey);
//System.out.println(strPubKey);
byte [] privKeyByte = Base64.decodeBase64(strPrivKey);
byte [] pubKeyByte = Base64.decodeBase64(strPubKey);
PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(privKeyByte);
//PKCS8EncodedKeySpec pubKeySpec = new PKCS8EncodedKeySpec(pubKeyByte);
//X509EncodedKeySpec privKeySpec = new X509EncodedKeySpec(privKeyByte);
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(pubKeyByte);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privKey = kf.generatePrivate(privKeySpec);
PublicKey pubKey = kf.generatePublic(pubKeySpec);
byte [] encryptByte = encrypt(s, pubKey);
System.out.println(decrypt(encryptByte, privKey));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

 

稍后提供一个PHP加密Java解密的实现

 

参考资料:

http:///questions/11787571/how-to-read-pem-file-to-get-private-and-public-key

http:///questions/8647165/how-to-sign-a-generic-text-with-rsa-key-and-encode-with-base64-in-java

http://www./tutorials/cryptography/rsa_encryption.shtml

http://snowolf./blog/381767

密钥结构及格式: https:///kb/cryptography/asn1-key-structures-in-der-and-pem

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多