java实现RSA公私钥PKCS8与PKCS1之间的相互转换(java RSA pkcs8转pkcs1,RSA pkcs1转pkcs8),PKCS8和PKCS1公私钥byte数组还原为java对象
目錄
- 前言
- 引入依賴
- 一、公鑰轉換
- 公鑰PKCS1轉PKCS8
- 公鑰PKCS8轉PKCS1
- 二、私鑰轉換
- 私鑰PKCS1轉PKCS8
- 私鑰PKCS8轉PKCS1
- 三、公鑰還原
- 公鑰byte數組還原為PKCS1 java對象
- 公鑰byte數組還原為PKCS8 java對象
- 四、私鑰還原
- 私鑰byte數組還原為PKCS1 java對象
- 私鑰byte數組還原為PKCS8 java對象
- 五、調用示例
- 完整代碼,包括RSA加解密、簽名驗簽
- 總結
前言
項目中底層生成的公私鑰都是pkcs1格式的,但是java中使用的都是pkcs8的,需要轉換。在網上找了很多方法, 但都不是很全面。并且網上大部分方法已經被標為過時了,寫在代碼里全是橫線,看著很不舒服。如圖中的RSAPrivateKeyStructure類已經不推薦使用,網上大部分還是用這種方式。
因此結合兩種標準的格式規定和bouncycastle的源碼,自己寫了以下的方法。
引入依賴
依賴bcprov-jdk15on包,以下方法均出自這個包。本人使用的1.51版本,親測可行。
方法一:
或引入下面的包,會自動引入上面的bcprov-jdk15on包
方法二:
因項目中使用了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 blocke.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 blocke.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 blocke.printStackTrace();} catch (IllegalBlockSizeException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (BadPaddingException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (NoSuchAlgorithmException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (NoSuchPaddingException e) {// TODO Auto-generated catch blocke.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 blocke.printStackTrace();} catch (NoSuchAlgorithmException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SignatureException e) {// TODO Auto-generated catch blocke.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中最少一個實例。
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版本。
總結
以上是生活随笔為你收集整理的java实现RSA公私钥PKCS8与PKCS1之间的相互转换(java RSA pkcs8转pkcs1,RSA pkcs1转pkcs8),PKCS8和PKCS1公私钥byte数组还原为java对象的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 生信SCi好用的画图软件
- 下一篇: Unity 动态切换天空盒\反射天空盒材