目录
前言
项目中底层生成的公私钥都是pkcs1格式的,但是java中使用的都是pkcs8的,需要转换。在网上找了很多方法, 但都不是很全面。并且网上大部分方法已经被标为过时了,写在代码里全是横线,看着很不舒服。如图中的RSAPrivateKeyStructure类已经不推荐使用,网上大部分还是用这种方式。
因此结合两种标准的格式规定和bouncycastle的源码,自己写了以下的方法。
引入依赖
依赖bcprov-jdk15on包,以下方法均出自这个包。本人使用的1.51版本,亲测可行。
方法一:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.51</version>
</dependency>
或引入下面的包,会自动引入上面的bcprov-jdk15on包
方法二:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.51</version>
</dependency>
因项目中使用了bcpkix-jdk15on包中的方法,所以需要两个包都引入,采用第二种方法引入。
导入的类
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.pkcs.RSAPrivateKey;
import org.bouncycastle.asn1.pkcs.RSAPublicKey;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
一、公钥转换
公钥PKCS1转PKCS8
public static byte[] formatPublicKeyPKCS1ToPKCS8(byte[] pkcs1PublicKeyByte) {
RSAPublicKey rsaPub = RSAPublicKey.getInstance(pkcs1PublicKeyByte);
byte[] pkcs8Bytes = null;
try {
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey generatePublic = kf.generatePublic(new RSAPublicKeySpec(rsaPub.getModulus(), rsaPub.getPublicExponent()));
pkcs8Bytes = generatePublic.getEncoded();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return pkcs8Bytes;
}
公钥PKCS8转PKCS1
public static byte[] formatPublicKeyPKCS8ToPKCS1(byte[] pkcs8PublicKeyByte) {
ASN1Sequence publicKeyASN1Object = ASN1Sequence.getInstance(pkcs8PublicKeyByte);
ASN1Encodable derBitStringASN1Encodable = publicKeyASN1Object.getObjectAt(1);
DERBitString derBitStringObject = DERBitString.getInstance(derBitStringASN1Encodable);
return derBitStringObject.getBytes();
}
二、私钥转换
私钥PKCS1转PKCS8
public static byte[] formatPrivateKeyPKCS1ToPKCS8(byte[] pkcs1PrivateKeyByte) {
AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PKCSObjectIdentifiers.pkcs8ShroudedKeyBag);
RSAPrivateKey privateKey = RSAPrivateKey.getInstance(pkcs1PrivateKeyByte);
//另一种方式
//ASN1Sequence privateKey = ASN1Sequence.getInstance(pkcs1PrivateKeyByte);
byte[] pkcs8Bytes = null;
try {
PrivateKeyInfo privKeyInfo = new PrivateKeyInfo(algorithmIdentifier, privateKey);
pkcs8Bytes = privKeyInfo.getEncoded();
} catch (IOException e) {
e.printStackTrace();
}
return pkcs8Bytes;
}
私钥PKCS8转PKCS1
方法一
public static byte[] formatPrivateKeyPKCS8ToPKCS1(byte[] pksc8PrivateKeyByte) {
PrivateKeyInfo pki = PrivateKeyInfo.getInstance(pksc8PrivateKeyByte);
byte[] pkcs1Bytes = null;
try {
ASN1Encodable parsePrivateKey = pki.parsePrivateKey();
pkcs1Bytes = parsePrivateKey.toASN1Primitive().getEncoded();
} catch (IOException e) {
e.printStackTrace();
}
return pkcs1Bytes;
}
方法二
public static byte[] formatPrivateKeyPKCS8ToPKCS1(byte[] pksc8PrivateKeyByte) {
PrivateKeyInfo pki = PrivateKeyInfo.getInstance(pksc8PrivateKeyByte);
byte[] pkcs1Bytes = null;
try {
RSAPrivateKey parsePrivateKey = RSAPrivateKey.getInstance(pki.parsePrivateKey());
pkcs1Bytes = parsePrivateKey.getEncoded();
} catch (IOException e) {
e.printStackTrace();
}
return pkcs1Bytes;
}
三、公钥还原
公钥byte数组还原为PKCS1 java对象
方法一(推荐)
public static RSAPublicKey formatPKCS1PublicKey(byte[] pkcs1PublicKeyByte) {
RSAPublicKey publicKey = RSAPublicKey.getInstance(pkcs1PublicKeyByte);
return publicKey;
}
方法二
public static ASN1Encodable formatPKCS1PublicKey(byte[] pkcs1PublicKeyByte) {
ASN1Sequence publicKey = ASN1Sequence.getInstance(pkcs1PublicKeyByte);
return publicKey;
}
公钥byte数组还原为PKCS8 java对象
public static PublicKey formatPKCS8PublicKey(byte[] pkcs8PublicKeyByte) {
PublicKey publicKey = null;
EncodedKeySpec keySpec = new X509EncodedKeySpec(pkcs8PublicKeyByte);
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
publicKey = keyFactory.generatePublic(keySpec);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return publicKey;
}
四、私钥还原
私钥byte数组还原为PKCS1 java对象
方法一(推荐)
public static RSAPrivateKey formatPKCS1PrivateKey(byte[] pkcs1PrivateKeyByte) {
RSAPrivateKey privateKey = RSAPrivateKey.getInstance(pkcs1PrivateKeyByte);
return privateKey;
}
方法二
public static ASN1Encodable formatPKCS1PrivateKey_2(byte[] pkcs1PrivateKeyByte) {
ASN1Sequence privateKey = ASN1Sequence.getInstance(pkcs1PrivateKeyByte);
return privateKey;
}
私钥byte数组还原为PKCS8 java对象
public static PrivateKey formatPKCS8PrivateKey(byte[] pkcs8PrivateKeyByte) {
PrivateKey privateKey = null;
EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pkcs8PrivateKeyByte);
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
privateKey = keyFactory.generatePrivate(keySpec);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return privateKey;
}
五、调用示例
static byte[] pkcs1PrivateKeyByte=Base64.decode("MIICXgIBAAKBgQC/Iv5ebLS2QoU/F88jSvrTpMxh0S3fKFy9/VOvdasZ3Bro+sf6kU//WI5crqidiQA4m2NxckMHUc/FUPazAQto/bPJDVagk9rB+UahTZ6gzxfTa4GkpM3jTXAppJfls9Qu1IzLLXoKgsT91wYdm21e1/4otmagTYa5pwAiwfACEQIDAQABAoGBAIy1/1uWXad760pahdSuo19iCFDOxR1vQm9f6tbWIoNkJa90x/owNht+nzeeIWXwcOg7hQcEnlHqKbJSe3umfjWjk35MoV06imNwDa3joF5shVGBVGtKHPcboDGniCONO+HyIc9UNNi84pWXHFlijV5fDmec6odUpsqWmkxXPQetAkEA63V/cnns4W//0ZQLMv0OnJg5fDECAFB189OTj0A6kILfBuTfUpDPA/ioUGU4r8r2jHy+1b6cUD68gvbAAGVgmwJBAM/PpZhLuIKQYNcTwYbmOGCb9OMoxezAXI2mzzsTIU0fHEVnWYvssTYDf5PqRMeaOzECJnUbjvFWMRnCbbRvBMMCQCTUVSIH1jiQ9zfF61aHZKCz4tH9LG32J+0CnCMdDcwK3G3MoO3ePrNFUrZ4jrxYh+YDoSn3zaVzmrL1e6TUNp8CQQCgw7cL1qhq+V6xhKsWvUuoEX6lrYlQ2o+/VejDfs0oaITqfEWeJgICEzrDJ10GPZ7FDzDJMASpV1Cs6OkNyUUZAkEAuSkubxXXJTqaTha8JI+Fa6Db6XUqv0A2f4hmt8hqFgBbUCZRkayKVRo0J9roSffGCvt/T4MKcXbUss7/OEVaKg==");
static byte[] pkcs1PublicKeyByte=Base64.decode("MIGJAoGBAL8i/l5stLZChT8XzyNK+tOkzGHRLd8oXL39U691qxncGuj6x/qRT/9YjlyuqJ2JADibY3FyQwdRz8VQ9rMBC2j9s8kNVqCT2sH5RqFNnqDPF9NrgaSkzeNNcCmkl+Wz1C7UjMstegqCxP3XBh2bbV7X/ii2ZqBNhrmnACLB8AIRAgMBAAE=");
public static void getKeyPair() {
//pkcs1公钥转pkcs8 pkcs8公钥还原
PublicKey publicKey2 = formatPKCS8PublicKey(formatPublicKeyPKCS1ToPKCS8(pkcs1PublicKeyByte));
//pkcs1私钥转pkcs8 pkcs8私钥还原
PrivateKey privateKey2 = formatPKCS8PrivateKey(formatPrivateKeyPKCS1ToPKCS8(pkcs1PrivateKeyByte));
//pkcs8私钥转pkcs1 pkcs1私钥还原
formatPKCS1PrivateKey(formatPrivateKeyPKCS8ToPKCS1(privateKey2.getEncoded()));
//pkcs8公钥转pkcs1 pkcs1公钥还原
formatPKCS1PublicKey(formatPublicKeyPKCS8ToPKCS1(publicKey2.getEncoded()));
}
完整代码,包括RSA加解密、签名验签
package com.CryptTest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SignatureException;
import java.security.spec.EncodedKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.pkcs.RSAPrivateKey;
import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure;
import org.bouncycastle.asn1.pkcs.RSAPublicKey;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import cn.hutool.core.codec.Base64;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/**
* RSA算法实现过程为:
1. 随意选择两个大的质数p和q,p不等于q,计算N=pq。
2. 根据欧拉函数,不大于N且与N互质的整数個数為(p-1)(q-1)。
3. 选择一个整数e与(p-1)(q-1)互质,并且e小于(p-1)(q-1)。
4. 用以下这个公式计算d:d× e ≡ 1 (mod (p-1)(q-1))。
5. 将p和q的记录销毁。
以上内容中,(N,e)是公钥,(N,d)是私钥。
* @author Administrator
*
*/
public class RSADemo {
/** *//**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117;
static byte[] pkcs1PrivateKeyByte=Base64.decode("MIICXgIBAAKBgQC/Iv5ebLS2QoU/F88jSvrTpMxh0S3fKFy9/VOvdasZ3Bro+sf6kU//WI5crqidiQA4m2NxckMHUc/FUPazAQto/bPJDVagk9rB+UahTZ6gzxfTa4GkpM3jTXAppJfls9Qu1IzLLXoKgsT91wYdm21e1/4otmagTYa5pwAiwfACEQIDAQABAoGBAIy1/1uWXad760pahdSuo19iCFDOxR1vQm9f6tbWIoNkJa90x/owNht+nzeeIWXwcOg7hQcEnlHqKbJSe3umfjWjk35MoV06imNwDa3joF5shVGBVGtKHPcboDGniCONO+HyIc9UNNi84pWXHFlijV5fDmec6odUpsqWmkxXPQetAkEA63V/cnns4W//0ZQLMv0OnJg5fDECAFB189OTj0A6kILfBuTfUpDPA/ioUGU4r8r2jHy+1b6cUD68gvbAAGVgmwJBAM/PpZhLuIKQYNcTwYbmOGCb9OMoxezAXI2mzzsTIU0fHEVnWYvssTYDf5PqRMeaOzECJnUbjvFWMRnCbbRvBMMCQCTUVSIH1jiQ9zfF61aHZKCz4tH9LG32J+0CnCMdDcwK3G3MoO3ePrNFUrZ4jrxYh+YDoSn3zaVzmrL1e6TUNp8CQQCgw7cL1qhq+V6xhKsWvUuoEX6lrYlQ2o+/VejDfs0oaITqfEWeJgICEzrDJ10GPZ7FDzDJMASpV1Cs6OkNyUUZAkEAuSkubxXXJTqaTha8JI+Fa6Db6XUqv0A2f4hmt8hqFgBbUCZRkayKVRo0J9roSffGCvt/T4MKcXbUss7/OEVaKg==");
static byte[] pkcs1PublicKeyByte=Base64.decode("MIGJAoGBAL8i/l5stLZChT8XzyNK+tOkzGHRLd8oXL39U691qxncGuj6x/qRT/9YjlyuqJ2JADibY3FyQwdRz8VQ9rMBC2j9s8kNVqCT2sH5RqFNnqDPF9NrgaSkzeNNcCmkl+Wz1C7UjMstegqCxP3XBh2bbV7X/ii2ZqBNhrmnACLB8AIRAgMBAAE=");
private PublicKey publicKey;
private PrivateKey privateKey;
public static void main(String[] args) {
signTest();
getKeyPair();
}
public static void signTest() {
RSADemo rsa=new RSADemo();
byte[] data="123".getBytes();
//加密 此处用公钥加密 也可以反过来 用私钥加密 用公钥解密
byte []eData=rsa.encryptData(data, rsa.publicKey);
String eDataEncode=new BASE64Encoder().encode(eData);
System.out.println("加密后: "+eDataEncode);
//解密
try {
byte[] dData=rsa.decryptData(new BASE64Decoder().decodeBuffer(eDataEncode), rsa.privateKey);
System.out.println("解密后: "+new String(dData));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String SIGN_sha256 = "SHA256WithRSA";
String SIGN_sh1 = "SHA1WithRSA";
String sign = rsa.sign(data,SIGN_sha256);
String sign2 = rsa.sign(data,SIGN_sh1);
//签名
System.out.println(SIGN_sha256+"签名:"+sign);
System.out.println(SIGN_sh1+" 签名:"+sign2);
boolean verify = rsa.verify(data,sign,SIGN_sha256);
boolean verify2 = rsa.verify(data,sign2,SIGN_sh1);
System.out.println(SIGN_sha256+"验签:"+verify);
System.out.println(SIGN_sh1+"验签:"+verify2);
}
public static void getKeyPair() {
//通过byte[]可以再度将公钥或私钥还原出来
PublicKey publicKey2 = formatPKCS8PublicKey(formatPublicKeyPKCS1ToPKCS8(pkcs1PublicKeyByte));
PrivateKey privateKey2 = formatPKCS8PrivateKey(formatPrivateKeyPKCS1ToPKCS8(pkcs1PrivateKeyByte));
RSAPrivateKey formatPKCS1PrivateKey = formatPKCS1PrivateKey(formatPrivateKeyPKCS8ToPKCS1(privateKey2.getEncoded()));
RSAPrivateKey formatPKCS1PrivateKey_2 = formatPKCS1PrivateKey(formatPrivateKeyPKCS8ToPKCS1_2(privateKey2.getEncoded()));
ASN1Encodable formatPKCS1PrivateKey_2_2 = formatPKCS1PrivateKey_2(formatPrivateKeyPKCS8ToPKCS1_2(privateKey2.getEncoded()));
RSAPublicKey formatPKCS1PublicKey = formatPKCS1PublicKey(formatPublicKeyPKCS8ToPKCS1(publicKey2.getEncoded()));
ASN1Encodable formatPKCS1PublicKey_2 = formatPKCS1PublicKey_2(formatPublicKeyPKCS8ToPKCS1(publicKey2.getEncoded()));
}
public static byte[] formatPrivateKeyPKCS1ToPKCS8(byte[] pkcs1PrivateKeyByte) {
AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PKCSObjectIdentifiers.pkcs8ShroudedKeyBag);
RSAPrivateKey privateKey = RSAPrivateKey.getInstance(pkcs1PrivateKeyByte);
//另一种方式
ASN1Sequence privateKey1 = ASN1Sequence.getInstance(pkcs1PrivateKeyByte);
byte[] pkcs8Bytes = null;
try {
PrivateKeyInfo privKeyInfo = new PrivateKeyInfo(algorithmIdentifier, privateKey);
PrivateKeyInfo privKeyInfo1 = new PrivateKeyInfo(algorithmIdentifier, privateKey1);
pkcs8Bytes = privKeyInfo.getEncoded();
} catch (IOException e) {
e.printStackTrace();
}
return pkcs8Bytes;
}
public static byte[] formatPrivateKeyPKCS8ToPKCS1(byte[] pksc8PrivateKeyByte) {
PrivateKeyInfo pki = PrivateKeyInfo.getInstance(pksc8PrivateKeyByte);
byte[] pkcs1Bytes = null;
try {
ASN1Encodable parsePrivateKey = pki.parsePrivateKey();
pkcs1Bytes = parsePrivateKey.toASN1Primitive().getEncoded();
} catch (IOException e) {
e.printStackTrace();
}
return pkcs1Bytes;
}
public static byte[] formatPrivateKeyPKCS8ToPKCS1_2(byte[] pksc8PrivateKeyByte) {
PrivateKeyInfo pki = PrivateKeyInfo.getInstance(pksc8PrivateKeyByte);
byte[] pkcs1Bytes = null;
try {
RSAPrivateKey parsePrivateKey = RSAPrivateKey.getInstance(pki.parsePrivateKey());
pkcs1Bytes = parsePrivateKey.getEncoded();
} catch (IOException e) {
e.printStackTrace();
}
return pkcs1Bytes;
}
public static byte[] formatPublicKeyPKCS1ToPKCS8(byte[] pkcs1PublicKeyByte) {
RSAPublicKey rsaPub = RSAPublicKey.getInstance(pkcs1PublicKeyByte);
byte[] pkcs8Bytes = null;
try {
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey generatePublic = kf.generatePublic(new RSAPublicKeySpec(rsaPub.getModulus(), rsaPub.getPublicExponent()));
pkcs8Bytes = generatePublic.getEncoded();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return pkcs8Bytes;
}
public static RSAPrivateKeyStructure formatPkcs8ToPkcs1(String rawKey) throws Exception {
PrivateKeyInfo pki = PrivateKeyInfo.getInstance(pkcs1PrivateKeyByte);
RSAPrivateKeyStructure pkcs1Key = RSAPrivateKeyStructure.getInstance(pki.getPrivateKey());
return pkcs1Key;
}
public static byte[] formatPublicKeyPKCS8ToPKCS1(byte[] pkcs8PublicKeyByte) {
ASN1Sequence publicKeyASN1Object = ASN1Sequence.getInstance(pkcs8PublicKeyByte);
ASN1Encodable derBitStringASN1Encodable = publicKeyASN1Object.getObjectAt(1);
DERBitString derBitStringObject = DERBitString.getInstance(derBitStringASN1Encodable);
return derBitStringObject.getBytes();
}
public static RSAPublicKey formatPKCS1PublicKey(byte[] pkcs1PublicKeyByte) {
RSAPublicKey publicKey = RSAPublicKey.getInstance(pkcs1PublicKeyByte);
return publicKey;
}
public static ASN1Encodable formatPKCS1PublicKey_2(byte[] pkcs1PublicKeyByte) {
ASN1Sequence publicKey = ASN1Sequence.getInstance(pkcs1PublicKeyByte);
return publicKey;
}
public static RSAPrivateKey formatPKCS1PrivateKey(byte[] pkcs1PrivateKeyByte) {
RSAPrivateKey privateKey = RSAPrivateKey.getInstance(pkcs1PrivateKeyByte);
return privateKey;
}
public static ASN1Encodable formatPKCS1PrivateKey_2(byte[] pkcs1PrivateKeyByte) {
ASN1Sequence privateKey = ASN1Sequence.getInstance(pkcs1PrivateKeyByte);
return privateKey;
}
public RSADemo() {
try {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(1024);// 密钥位数
// 动态生成密钥对
KeyPair keyPair = keyPairGen.generateKeyPair();
// 公钥
publicKey = keyPair.getPublic();
// 私钥
privateKey = keyPair.getPrivate();
//获得公钥私钥的比特编码
byte[] publicKeyByte=publicKey.getEncoded();
byte[] privateKeyByte=privateKey.getEncoded();
//通过byte[]可以再度将公钥或私钥还原出来
formatPKCS8PublicKey(publicKeyByte);
formatPKCS8PrivateKey(privateKeyByte);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 用公钥加密
* @param publicKey
* @return
*/
public byte[] encryptData(byte[] data,PublicKey publicKey) {
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
// 加密前设定加密方式及密钥
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
// 传入编码数据并返回编码结果
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
//不分段加密
//encryptedData=cipher.doFinal(data);
return encryptedData;
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* 用私钥解密
*
* @param encryptedData 经过encryptedData()加密返回的byte数据
* @param privateKey 私钥
* @return
*/
public byte[] decryptData(byte[] encryptedData, PrivateKey privateKey)
{
try
{
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(encryptedData);
} catch (Exception e)
{
e.printStackTrace();
return null;
}
}
/**
* 通过公钥byte[]将公钥还原,适用于RSA算法
* @param pkcs8PublicKeyByte
* @return
*/
public static PublicKey formatPKCS8PublicKey(byte[] pkcs8PublicKeyByte) {
PublicKey publicKey = null;
EncodedKeySpec keySpec = new X509EncodedKeySpec(pkcs8PublicKeyByte);
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
publicKey = keyFactory.generatePublic(keySpec);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return publicKey;
}
/**
* 通过私钥byte[]将公钥还原,适用于RSA算法
* @param pkcs8PrivateKeyByte
* @return
*/
public static PrivateKey formatPKCS8PrivateKey(byte[] pkcs8PrivateKeyByte) {
PrivateKey privateKey = null;
EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pkcs8PrivateKeyByte);
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
privateKey = keyFactory.generatePrivate(keySpec);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return privateKey;
}
public String sign(byte[] data,String SIGN_ALGORITHMS) {
try {
java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
signature.initSign(privateKey);
signature.update(data);
byte[] signed = signature.sign();
return Base64.encode(signed);
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SignatureException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public boolean verify(byte[] srcData, String sign,String SIGN_ALGORITHMS)
{
try
{
java.security.Signature signature = java.security.Signature
.getInstance(SIGN_ALGORITHMS);
signature.initVerify(publicKey);
signature.update(srcData);
boolean bverify = signature.verify( Base64.decode(sign) );
return bverify;
}
catch (Exception e)
{
e.printStackTrace();
}
return false;
}
}
总结
以上同一个转换有两种方法的,其实原理都一样。区别在于一个转为标准中规定的结构体,便于获取其中的数据。另一个转为ASN1Encodable,是一个ASN1结构体,同样可以根据数据索引获取其中的数据。
PKCS #1 RSA公钥的ASN.1类型
RSAPublicKey ::= SEQUENCE {
modulus INTEGER, -- n
publicExponent INTEGER -- e
}
RSAPublic的属性有如下意义:
modulus是RSA的模数n。
publicExponent是RSA的公共指数e。
PKCS #1 RSA私钥的ASN.1类型
RSAPrivateKey ::= SEQUENCE {
version Version,
modulus INTEGER, -- n
publicExponent INTEGER, -- e
privateExponent INTEGER, -- d
prime1 INTEGER, -- p
prime2 INTEGER, -- q
exponent1 INTEGER, -- d mod (p-1)
exponent2 INTEGER, -- d mod (q-1)
coefficient INTEGER, -- (inverse of q) mod p
otherPrimeInfos OtherPrimeInfos OPTIONAL
}
RSAPrivateKey的属性有如下意义:
#version 为了兼容未来的修订提出的版本号。本文的版本,多质数为1,其它则为0.
Version ::= INTEGER { two-prime(0), multi(1) }
(CONSTRAINED BY {-- version must be multi if otherPrimeInfos present --})
# modulus 是RSA模数n
# publicExponent 是RSA公有指数e
# privateExponent 是RSA私有质数d
# prime1 是n的质数因子p
# prime2 是n的质数因子q
# exponent1 是d mod(p-1)
# exponent2 是d mod(q-1)
# coefficient 是CRT系数 q-1 mod p
# otherPrimeInfos 按顺序包含了附加的质数 r3----ru。它在版本0的时候不存在,将包含在版本1中最少一个实例。
OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
OtherPrimeInfo ::= SEQUENCE {
prime INTEGER, -- ri
exponent INTEGER, -- di
coefficient INTEGER -- ti
}
OtherPrimeInfo的属性有如下的含义:
#prime是n的质数因子ri,i>=3.
#exponent是 di = d mod(ri-1)
#coefficient是CRT系数 ti = (r1r2…ri-1) mod ri
PKCS #8 RSA私钥的ASN.1类型
名词解释
pkcs1:PKCS #1 RSA密码编译标准(RSA Cryptography Standard)2.1版本。定义了RSA的数理基础、公/私钥格式,以及加/解密、签/验章的流程。1.5版本曾经遭到攻击。
pkcs8:PKCS #8 私钥消息表示标准(Private-Key Information Syntax Standard) 1.2版本。