openssl pkcs8 -topk8 -in rsa_private_key.pem -outpkcs8_rsa_private_key.pem -nocrypt
由于php 进行openssl_public_encrypt 加密后返回的是二进制数据,需要对其返回的加密后的数据进行二进制16进制编码base64_encode才可以显示,相应的java生产加密后生产的16进制加密字符串需要进行base64_decode进行机密后在进行openssl_private_decrypt,例如:openssl_private_decrypt(base64_decode($encryptData), $decryptData,$privateKey);
$privateKeyFilePath = '-----BEGIN RSAPRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJutuj8lo8lMkuX7
qF9mbu64siu3+GK9ot+i3fbCr+dLOhKxiSg2TbtjL6fXQ4Ohnvn/3VjxCgkp6hZ7
QiTUfUOYy7AR/d4GgEIWf542OBmrpIhUEI0SdRpLRJOZaoY8UpEUnVSN3islDW0Y
UbfPe/0LDZsqrjUABgwPtmou/bN9AgMBAAECgYA7MOS9mbwaj4jS9Mph63qGPadQ
xBQmxt+klDI83m0vTgT4kpQJvAv2EZJPCKPc6pidiVFJvewI6+zbO2Y8xqYRc6Ut
RvZKIVD2ECmJ7mvsCt2yJLP44j7Gu3xD3NL12dgv8kyZoqdIfHfFWKlI2sPizFVo
IsO/vuT7ngC07uJkKQJBAM5EL0HhSR+t9R23oWk6mFy0tsh6POXWgpvVt2jAuwYP
VDvwkbNTSdkh5oFNMiEUuN1w5fA6p1dh+Fe2ZJEcgdMCQQDBNwJx7UUzzSZPhA6N
2YBVo09qHUCOWK4kEgNc32+k/f6/Rcx/ghL2USJv/d6r6Ne6DS32ix2we4ghUpzk
DlNvAkEAjaICNSGFvYwMmLhDzGbgwh+Qtv5AnK18B5drljFo+pNCCtp4oYMaXU9K
4RRpzI9XFS71pMwRpg3uogPq8D174wJBAJrZp4//BTNa+5VG1RNCeeQomoEFKLPs
xsQJ28AXIrctCXnqStb2PJREukDfShKk7iAiZ+/r1sOWfaeXOj5cbOkCQGKATKxy
ad5K+z2PvzKFMoqLK+uRJFS4RHdefUaYshfCdMmoklyFjtk53RJ4WHAcY5TLBvbz
56WtrXK/09rNqfI=
-----END RSA PRIVATE KEY-----';
* 公钥文件的路径
$publicKeyFilePath = '-----BEGIN PUBLICKEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbrbo/JaPJTJLl+6hfZm7uuLIr
t/hivaLfot32wq/nSzoSsYkoNk27Yy+n10ODoZ75/91Y8QoJKeoWe0Ik1H1DmMuw
Ef3eBoBCFn+eNjgZq6SIVBCNEnUaS0STmWqGPFKRFJ1Ujd4rJQ1tGFG3z3v9Cw2b
Kq41AAYMD7ZqLv2zfQIDAQAB
-----END PUBLIC KEY-----';
extension_loaded('openssl') or die('php需要openssl扩展支持');
* 生成Resource类型的密钥,如果密钥文件内容被破坏,openssl_pkey_get_private函数返回false
$privateKey =openssl_pkey_get_private($privateKeyFilePath);
* 生成Resource类型的公钥,如果公钥文件内容被破坏,openssl_pkey_get_public函数返回false
$publicKey =openssl_pkey_get_public($publicKeyFilePath);
($privateKey) or die('密钥不可用');
($publicKey) or die('公钥不可用');
* 原数据
$originalData = '我是PHP版本';
* 加密以后的数据,用于在网路上传输
$encryptData = '';
echo '原数据为:', $originalData, '<br />';
///////////////////////////////用公钥加密////////////////////////
if (openssl_public_encrypt($originalData,$encryptData, $publicKey)) {
echo '加密成功,加密后数据(base64_encode后)为:', base64_encode($encryptData), '<br />';
echo '加密成功,加密后数据(bin2hex后)为:',bin2hex($encryptData), '<br/>';
} else {
die('加密失败');
///////////////////////////////用私钥解密////////////////////////
$decryptData ='';
if (openssl_private_decrypt($encryptData,$decryptData, $privateKey)) {
echo '解密成功,解密后数据为:',$decryptData, '<br />';
} else {
die('解密成功');
在网上查询了好几天,最终找到解决方案,网络上都是通过Cipher.
getInstance
("RSA");
而改成Cipher.
getInstance
("RSA/ECB/PKCS1Padding");就可以实现与php版本公钥和密钥互通了。
package
RSA.test;
import
java.io.BufferedReader;
import
java.io.IOException;
import
java.io.InputStream;
import
java.io.InputStreamReader;
import
java.security.InvalidKeyException;
import
java.security.Key;
import
java.security.KeyFactory;
import
java.security.KeyPair;
import
java.security.KeyPairGenerator;
import
java.security.NoSuchAlgorithmException;
import
java.security.SecureRandom;
import
java.security.interfaces.RSAPrivateKey;
import
java.security.interfaces.RSAPublicKey;
import
java.security.spec.InvalidKeySpecException;
import
java.security.spec.PKCS8EncodedKeySpec;
import
java.security.spec.X509EncodedKeySpec;
import
javax.crypto.BadPaddingException;
import
javax.crypto.Cipher;
import
javax.crypto.IllegalBlockSizeException;
import
javax.crypto.NoSuchPaddingException;
import
org.bouncycastle.jce.provider.BouncyCastleProvider
;
import
sun.misc.BASE64Decoder;
import
sun.misc.BASE64Encoder;
publicclass
RSAEncrypt {
privatestaticfinal
String
DEFAULT_PUBLIC_KEY
="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbrbo/JaPJTJLl+6hfZm7uuLIrt/hivaLfot32wq/nSzoSsYkoNk27Yy+n10ODoZ75/91Y8QoJKeoWe0Ik1H1DmMuwEf3eBoBCFn+eNjgZq6SIVBCNEnUaS0STmWqGPFKRFJ1Ujd4rJQ1tGFG3z3v9Cw2bKq41AAYMD7ZqLv2zfQIDAQAB";
privatestaticfinal
String
DEFAULT_PRIVATE_KEY
="MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJutuj8lo8lMkuX7qF9mbu64siu3+GK9ot+i3fbCr+dLOhKxiSg2TbtjL6fXQ4Ohnvn/3VjxCgkp6hZ7QiTUfUOYy7AR/d4GgEIWf542OBmrpIhUEI0SdRpLRJOZaoY8UpEUnVSN3islDW0YUbfPe/0LDZsqrjUABgwPtmou/bN9AgMBAAECgYA7MOS9mbwaj4jS9Mph63qGPadQxBQmxt+klDI83m0vTgT4kpQJvAv2EZJPCKPc6pidiVFJvewI6+zbO2Y8xqYRc6UtRvZKIVD2ECmJ7mvsCt2yJLP44j7Gu3xD3NL12dgv8kyZoqdIfHfFWKlI2sPizFVoIsO/vuT7ngC07uJkKQJBAM5EL0HhSR+t9R23oWk6mFy0tsh6POXWgpvVt2jAuwYPVDvwkbNTSdkh5oFNMiEUuN1w5fA6p1dh+Fe2ZJEcgdMCQQDBNwJx7UUzzSZPhA6N2YBVo09qHUCOWK4kEgNc32+k/f6/Rcx/ghL2USJv/d6r6Ne6DS32ix2we4ghUpzkDlNvAkEAjaICNSGFvYwMmLhDzGbgwh+Qtv5AnK18B5drljFo+pNCCtp4oYMaXU9K4RRpzI9XFS71pMwRpg3uogPq8D174wJBAJrZp4//BTNa+5VG1RNCeeQomoEFKLPsxsQJ28AXIrctCXnqStb2PJREukDfShKk7iAiZ+/r1sOWfaeXOj5cbOkCQGKATKxyad5K+z2PvzKFMoqLK+uRJFS4RHdefUaYshfCdMmoklyFjtk53RJ4WHAcY5TLBvbz56WtrXK/09rNqfI=";
/*private static final StringDEFAULT_PUBLIC_KEY="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbrbo/JaPJTJLl+6hfZm7uuLIr"+"\r"
+"t/hivaLfot32wq/nSzoSsYkoNk27Yy+n10ODoZ75/91Y8QoJKeoWe0Ik1H1DmMuw"+"\r"
+"Ef3eBoBCFn+eNjgZq6SIVBCNEnUaS0STmWqGPFKRFJ1Ujd4rJQ1tGFG3z3v9Cw2b"+"\r"
+"Kq41AAYMD7ZqLv2zfQIDAQAB"+"\r";
private static final StringDEFAULT_PRIVATE_KEY="MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJutuj8lo8lMkuX7"+"\r"
+"qF9mbu64siu3+GK9ot+i3fbCr+dLOhKxiSg2TbtjL6fXQ4Ohnvn/3VjxCgkp6hZ7"+"\r"
+"QiTUfUOYy7AR/d4GgEIWf542OBmrpIhUEI0SdRpLRJOZaoY8UpEUnVSN3islDW0Y"+"\r"
+"UbfPe/0LDZsqrjUABgwPtmou/bN9AgMBAAECgYA7MOS9mbwaj4jS9Mph63qGPadQ"+"\r"
+"xBQmxt+klDI83m0vTgT4kpQJvAv2EZJPCKPc6pidiVFJvewI6+zbO2Y8xqYRc6Ut"+"\r"
+"RvZKIVD2ECmJ7mvsCt2yJLP44j7Gu3xD3NL12dgv8kyZoqdIfHfFWKlI2sPizFVo"+"\r"
+"IsO/vuT7ngC07uJkKQJBAM5EL0HhSR+t9R23oWk6mFy0tsh6POXWgpvVt2jAuwYP"+"\r"
+"VDvwkbNTSdkh5oFNMiEUuN1w5fA6p1dh+Fe2ZJEcgdMCQQDBNwJx7UUzzSZPhA6N"+"\r"
+"2YBVo09qHUCOWK4kEgNc32+k/f6/
Rcx
/ghL2USJv/d6r6Ne6DS32ix2we4ghUpzk"+"\r"
+"DlNvAkEAjaICNSGFvYwMmLhDzGbgwh+Qtv5AnK18B5drljFo+pNCCtp4oYMaXU9K"+"\r"
+"4RRpzI9XFS71pMwRpg3uogPq8D174wJBAJrZp4//BTNa+5VG1RNCeeQomoEFKLPs"+"\r"
+"xsQJ28AXIrctCXnqStb2PJREukDfShKk7iAiZ+/r1sOWfaeXOj5cbOkCQGKATKxy"+"\r"
+"ad5K+z2PvzKFMoqLK+uRJFS4RHdefUaYshfCdMmoklyFjtk53RJ4WHAcY5TLBvbz"+"\r"
+"56WtrXK/09rNqfI="+"\r";*/
private
RSAPrivateKey privateKey;
private
RSAPublicKey publicKey;
* 字节数据转字符串专用集合
privatestaticfinalchar
[]
HEX_CHAR
= {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
* 获取私钥
*
@return
当前的私钥对象
public
RSAPrivateKey getPrivateKey() {
return
privateKey;
* 获取公钥
*
@return
当前的公钥对象
public
RSAPublicKey getPublicKey() {
return
publicKey;
* 随机生成密钥对
publicvoid
genKeyPair(){
KeyPairGeneratorkeyPairGen=
null
;
try
{
keyPairGen=KeyPairGenerator.
getInstance
("RSA");
}
catch
(NoSuchAlgorithmException e) {
e.printStackTrace();
keyPairGen.initialize(1024,
new
SecureRandom());
KeyPair keyPair=keyPairGen.generateKeyPair();
this
.privateKey= (RSAPrivateKey) keyPair.getPrivate();
this
.publicKey= (RSAPublicKey)keyPair.getPublic();
* 从文件中输入流中加载公钥
*
@param
in 公钥输入流
*
@throws
Exception 加载公钥时产生的异常
publicvoid
loadPublicKey(InputStreamin)
throws
Exception{
try
{
BufferedReaderbr=
new
BufferedReader(
new
InputStreamReader(in));
String readLine=
null
;
StringBuildersb=
new
StringBuilder();
while
((readLine= br.readLine())!=
null
){
if
(readLine.charAt(0)=='-'){
continue
;
}
else
{
sb.append(readLine);
sb.append('\r');
loadPublicKey(sb.toString());
}
catch
(IOException e) {
thrownew
Exception("公钥数据流读取错误");
}
catch
(NullPointerException e) {
thrownew
Exception("公钥输入流为空");
* 从字符串中加载公钥
*
@param
publicKeyStr 公钥数据字符串
*
@throws
Exception 加载公钥时产生的异常
publicvoid
loadPublicKey(StringpublicKeyStr)
throws
Exception{
try
{
BASE64Decoderbase64Decoder=
new
BASE64Decoder();
byte
[] buffer= base64Decoder.decodeBuffer(publicKeyStr);
KeyFactorykeyFactory= KeyFactory.
getInstance
("RSA");
X509EncodedKeySpec keySpec=
new
X509EncodedKeySpec(buffer);
this
.publicKey= (RSAPublicKey) keyFactory.generatePublic(keySpec);
}
catch
(NoSuchAlgorithmException e) {
thrownew
Exception("无此算法");
}
catch
(InvalidKeySpecException e) {
thrownew
Exception("公钥非法");
}
catch
(IOException e) {
thrownew
Exception("公钥数据内容读取错误");
}
catch
(NullPointerException e) {
thrownew
Exception("公钥数据为空");
* 从文件中加载私钥
*
@param
keyFileName 私钥文件名
*
@return
是否成功
*
@throws
Exception
publicvoid
loadPrivateKey(InputStreamin)
throws
Exception{
try
{
BufferedReader br=
new
BufferedReader(
new
InputStreamReader(in));
String readLine=
null
;
StringBuildersb=
new
StringBuilder();
while
((readLine= br.readLine())!=
null
){
if
(readLine.charAt(0)=='-'){
continue
;
}
else
{
sb.append(readLine);
sb.append('\r');
loadPrivateKey(sb.toString());
}
catch
(IOException e) {
thrownew
Exception("私钥数据读取错误");
}
catch
(NullPointerException e) {
thrownew
Exception("私钥输入流为空");
publicvoid
loadPrivateKey(StringprivateKeyStr)
throws
Exception{
try
{
BASE64Decoder base64Decoder=
new
BASE64Decoder();
byte
[] buffer= base64Decoder.decodeBuffer(privateKeyStr);
PKCS8EncodedKeySpec keySpec=
new
PKCS8EncodedKeySpec(buffer);
KeyFactorykeyFactory= KeyFactory.
getInstance
("RSA");
this
.privateKey= (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
}
catch
(NoSuchAlgorithmException e) {
thrownew
Exception("无此算法");
}
catch
(InvalidKeySpecException e) {
thrownew
Exception("私钥非法");
}
catch
(IOException e) {
thrownew
Exception("私钥数据内容读取错误");
}
catch
(NullPointerException e) {
thrownew
Exception("私钥数据为空");
* 加密过程
*
@param
publicKey 公钥
*
@param
plainTextData 明文数据
*
@return
*
@throws
Exception 加密过程中的异常信息
publicbyte
[] encrypt(RSAPublicKeypublicKey,
byte
[] plainTextData)
throws
Exception{
if
(publicKey==
null
){
thrownew
Exception("加密公钥为空, 请设置");
Cipher cipher=
null
;
try
{
cipher= Cipher.
getInstance
("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.
ENCRYPT_MODE
, publicKey);
byte
[] output= cipher.doFinal(plainTextData);
return
output;
}
catch
(NoSuchAlgorithmException e) {
thrownew
Exception("无此加密算法");
}
catch
(NoSuchPaddingException e) {
e.printStackTrace();
returnnull
;
}
catch
(InvalidKeyException e) {
thrownew
Exception("加密公钥非法,请检查");
}
catch
(IllegalBlockSizeException e) {
thrownew
Exception("明文长度非法");
}
catch
(BadPaddingException e) {
thrownew
Exception("明文数据已损坏");
* 解密过程
*
@param
privateKey 私钥
*
@param
cipherData 密文数据
*
@return
明文
*
@throws
Exception 解密过程中的异常信息
publicbyte
[] decrypt(RSAPrivateKeyprivateKey,
byte
[] cipherData)
throws
Exception{
if
(privateKey==
null
){
thrownew
Exception("解密私钥为空, 请设置");
Cipher cipher=
null
;
try
{
cipher= Cipher.
getInstance
("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.
DECRYPT_MODE
, privateKey);
byte
[] output= cipher.doFinal(cipherData);
return
output;
}
catch
(NoSuchAlgorithmException e) {
thrownew
Exception("无此解密算法");
}
catch
(NoSuchPaddingException e) {
e.printStackTrace();
returnnull
;
}
catch
(InvalidKeyException e) {
thrownew
Exception("解密私钥非法,请检查");
}
catch
(IllegalBlockSizeException e) {
thrownew
Exception("密文长度非法");
}
catch
(BadPaddingException e) {
thrownew
Exception("密文数据已损坏");
* 字节数据转十六进制字符串
*
@param
data 输入数据
*
@return
十六进制内容
publicstatic
String byteArrayToString(
byte
[] data){
StringBuilderstringBuilder=
new
StringBuilder();
for
(
int
i=0; i<data.length; i++){
//取出字节的高四位 作为索引得到相应的十六进制标识符 注意无符号右移
stringBuilder.append(
HEX_CHAR
[(data[i] & 0xf0)>>> 4]);
//取出字节的低四位 作为索引得到相应的十六进制标识符
stringBuilder.append(
HEX_CHAR
[(data[i] &0x0f)]);
/*if (i<data.length-1){
stringBuilder.append(' ');
return
stringBuilder.toString();
* 得到密钥字符串(经过base64编码)
*
@return
publicstatic
String getKeyString(Keykey)
throws
Exception {
byte
[] keyBytes = key.getEncoded();
String s = (
new
BASE64Encoder()).encode(keyBytes);
return
s;
publicstaticvoid
main(String[] args){
RSAEncryptrsaEncrypt=
new
RSAEncrypt();
//rsaEncrypt.genKeyPair();
//加载公钥
try
{
rsaEncrypt.loadPublicKey(RSAEncrypt.
DEFAULT_PUBLIC_KEY
);
System.
out
.println("加载公钥成功");
}
catch
(Exception e) {
System.
err
.println(e.getMessage());
System.
err
.println("加载公钥失败");
//加载私钥
try
{
rsaEncrypt.loadPrivateKey(RSAEncrypt.
DEFAULT_PRIVATE_KEY
);
System.
out
.println("加载私钥成功");
}
catch
(Exception e) {
System.
err
.println(e.getMessage());
System.
err
.println("加载私钥失败");
//测试字符串
String encryptStr= "duhuawei";
try
{
BASE64Encoder encoder =
new
BASE64Encoder();
BASE64Decoder decoder =
new
BASE64Decoder();
byte
[] cipher = rsaEncrypt.encrypt(rsaEncrypt.getPublicKey(),encryptStr.getBytes());
//cipher="fF7DHU9MpBOS0WFrmb7Xplq1ctrsNAPCOHLxmwSd+X/w1cVMQLaQHH3bJYx7mrVRRYzxhCmwOcA+jMXe5sDbGmMU7YJrQGyqLCpbERfqDUbU6bSiVO/lxWDW2cciSBTiffSOHxbJPGkK0SSROs9+leBObh7W9FqNRvH83GdFIq8=".getBytes();
System.
out
.println("密文长度:"+ cipher.length);
System.
out
.println(RSAEncrypt.
byteArrayToString
(cipher));
String des="LniZFIzbkYokH5DTSI5tus3H7Wt9bFzV7MmQIIeVRP6bhsheTGI4IPghne8W9TN3AVRioZsj5A7FINdthsnGpnQpG8BwH0OFJZLMy3ZaZhFu6FR0ipuLB9CP60u9W0jovzwEqdIcfqTf6fQzBbkJBLoMx3BhII0546wsNW8+POU=";
System.
out
.println("密文如下:"+encoder.encode(cipher));
byte
[] plainText = rsaEncrypt.decrypt(rsaEncrypt.getPrivateKey(),decoder.decodeBuffer(des));
//System.out.println("明文长度:"+plainText.length);
//System.out.println(RSAEncrypt.byteArrayToString(plainText));
System.
out
.println("解密后结果:"+
new
String(plainText));
}
catch
(Exception e) {
System.
err
.println(e.getMessage());