Java生成RSA密鑰對(duì)的兩種方法:
1台汇、RSAPublicKeySpec和RSAPrivateCrtKeySpec
這兩個(gè)API是JAVA安全模塊自帶的API亭姥,可以查看API的相關(guān)說(shuō)明:
public RSAPublicKeySpec(BigInteger modulus,BigInteger
publicExponent)
創(chuàng)建一個(gè)新的RSAPublicKeySpec稼钩。
參數(shù)
modulus - 模數(shù)
publicExponent - 公鑰指數(shù)
publicRSAPrivateCrtKeySpec(BigInteger modulus,
??????????????????????????? BigIntegerpublicExponent,
??????????? ????????????????BigInteger privateExponent,
??????????????????????????? BigInteger primeP,
??????????????????????????? BigInteger primeQ,
??????????????????????????? BigIntegerprimeExponentP,
??????????????????????????? BigIntegerprimeExponentQ,
??????? ????????????????????BigInteger crtCoefficient)
創(chuàng)建一個(gè)新的RSAPrivateCrtKeySpec給定在PKCS#1中定義的模數(shù),publicExponent达罗,privateExponent坝撑,primeP,primeQ粮揉,primeExponentP巡李,primeExponentQ和crtCoefficient。
參數(shù)
modulus - 模數(shù)n
publicExponent - 公鑰指數(shù)e
privateExponent -私鑰指數(shù)d
primeP - n的素因子p
primeQ - n的素因子q
primeExponentP - 這是d mod(p-1)
primeExponentQ - 這是d mod(q-1)
crtCoefficient - 剩余定理系數(shù)q-1 mod p
示例代碼如下:
// 創(chuàng)建指定公鑰的對(duì)象
RSAPublicKeySpec localRSAPublicKeySpec1 =
new RSAPublicKeySpec(new
BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7",
16), new BigInteger("11", 16));
// 創(chuàng)建指定私鑰的對(duì)象
RSAPrivateCrtKeySpec
localRSAPrivateCrtKeySpec1 = new RSAPrivateCrtKeySpec(new
BigInteger("b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7",
16), new BigInteger("11", 16), new
BigInteger("9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89",
16), new
BigInteger("c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb",
16), new BigInteger("f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5",
16), new
BigInteger("b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391",
16), new BigInteger("d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd",
16), new BigInteger("b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19",
16));
// 創(chuàng)建指定RSA算法的密鑰工廠扶认,指定工廠為BC
KeyFactory localKeyFactory =
KeyFactory.getInstance("RSA", "BC");
// 生成私鑰
PrivateKey localPrivateKey1 =
localKeyFactory.generatePrivate(localRSAPrivateCrtKeySpec1);
// 生成公鑰
PublicKey localPublicKey1 =
localKeyFactory.generatePublic(localRSAPublicKeySpec1);
2侨拦、KeyPair 和KeyPairGenerator
KeyPairGenerator類用于生成公鑰和私鑰對(duì)。 密鑰對(duì)生成器使用getInstance工廠方法(返回給定類的實(shí)例的靜態(tài)方法)構(gòu)造辐宾。
用于特定算法的密鑰對(duì)生成器創(chuàng)建可以與該算法一起使用的公鑰/私鑰對(duì)狱从。 它還將算法特定的參數(shù)與生成的每個(gè)密鑰相關(guān)聯(lián)。
生成密鑰對(duì)的方法有兩種:以算法無(wú)關(guān)的方式叠纹,并以算法特定的方式季研。
publicKeyPair(PublicKey publicKey, PrivateKey privateKey)
從給定的公鑰和私鑰構(gòu)造一個(gè)密鑰對(duì)。
請(qǐng)注意誉察,此構(gòu)造函數(shù)僅存儲(chǔ)對(duì)生成的密鑰對(duì)中的公鑰和私鑰組件的引用与涡。 這是安全的,因?yàn)镵ey對(duì)象是不可變的冒窍。
參數(shù)
publicKey - 公鑰递沪。
privateKey - 私鑰。
示例代碼如下:
// 生成RSA公私鑰對(duì)
KeyPairGenerator kpg = null;
// 采用 RSA 非對(duì)稱算法加密
kpg =KeyPairGenerator.getInstance("RSA");
// 初始化為2048 位
kpg.initialize(2048);
KeyPair keyPair = kpg.generateKeyPair();
// 公鑰
PublicKey pubKey =localKeyFactory.generatePublic(localRSAPublicKeySpec1);
// 私鑰
PrivateKey priKey = keyPair.getPrivate();
3综液、完整的示例代碼
packagecom.test;
importjava.io.File;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.math.BigInteger;
importjava.security.KeyPair;
importjava.security.KeyPairGenerator;
importjava.security.PrivateKey;
importjava.security.PublicKey;
importjava.security.Security;
importjava.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
importjava.util.Calendar;
importjava.util.Date;
importjava.util.Hashtable;
importjava.util.Vector;
importorg.bouncycastle.asn1.x509.KeyUsage;
importorg.bouncycastle.asn1.x509.X509Extension;
importorg.bouncycastle.jce.X509Principal;
importorg.bouncycastle.jce.provider.BouncyCastleProvider;
importorg.bouncycastle.x509.X509V3CertificateGenerator;
@SuppressWarnings("deprecation")
public class GenCrt {
? /**
?? ?*BouncyCastleProvider
?? ?*/
?? static {
????? Security.addProvider(new BouncyCastleProvider());
?? }
?/**
?? ?*生成 X509 證書
?? ?*@param user
?? ?*@return
?? ?*/
?? @SuppressWarnings({ "deprecation", "unchecked" })
?? public static byte[] generateCert() {
????? X509Certificatecert = null;
????? X509V3CertificateGeneratorcertGen=new X509V3CertificateGenerator();
????? try {
???????? // 生成RSA公私鑰對(duì)
???????? KeyPairGeneratorkpg = null;
???????? // 采用 RSA 非對(duì)稱算法加密
???????? kpg= KeyPairGenerator.getInstance("RSA");
???????? // 初始化為2048 位
???????? kpg.initialize(2048);
???????? KeyPairkeyPair = kpg.generateKeyPair();
???????? // 公鑰
???????? PublicKeypubKey = keyPair.getPublic();
???????? // 私鑰
???????? PrivateKeypriKey = keyPair.getPrivate();
???????? // 公鑰
???????? certGen.setPublicKey(pubKey);
???????? // 設(shè)置序列號(hào)
???????? certGen.setSerialNumber(new BigInteger("12345678"));
???????? // 設(shè)置頒發(fā)者信息
???????? @SuppressWarnings("rawtypes")
???????? HashtablekwMapIssuer = new Hashtable();
????? ??? @SuppressWarnings("rawtypes")
???????? VectorlocalVector = new Vector();
???????? kwMapIssuer.put(X509Principal.C,"CN");
???????? localVector.addElement(X509Principal.C);
???????? kwMapIssuer.put(X509Principal.CN,"wuwu");
???????? localVector.addElement(X509Principal.CN);
???????? kwMapIssuer.put(X509Principal.E, "111@qq.com");
???????? localVector.addElement(X509Principal.E);
???????? certGen.setIssuerDN(new X509Principal(localVector, kwMapIssuer));
???????? //? 設(shè)置申請(qǐng)者信息
???????? @SuppressWarnings("rawtypes")
???????? HashtablekwMapApplicant = new Hashtable();
????? ??? @SuppressWarnings("rawtypes")
???????? VectorlocalVectorApplicant = new Vector();
???????? kwMapApplicant.put(X509Principal.C,"CN");
???????? localVectorApplicant.addElement(X509Principal.C);
???????? kwMapApplicant.put(X509Principal.CN,"wlhl");
???????? localVectorApplicant.addElement(X509Principal.CN);
???????? kwMapApplicant.put(X509Principal.E, "123@qq.com");
???????? localVectorApplicant.addElement(X509Principal.E);
???????? certGen.setSubjectDN(new X509Principal(localVectorApplicant, kwMapApplicant));
???????? // 設(shè)置有效期
???????? Calendarc= Calendar.getInstance();
???????? c.set(Calendar.DAY_OF_YEAR, c.get(Calendar.DAY_OF_YEAR) + 7000);
???????? certGen.setNotBefore(new Date());
???????? certGen.setNotAfter(c.getTime());
???????? // 設(shè)置擴(kuò)展域款慨,密鑰用途
???????? certGen.addExtension(X509Extension.keyUsage, false, new?KeyUsage(KeyUsage.digitalSignature));
??????????? // 簽名算法
???????? certGen.setSignatureAlgorithm("SHA256WithRSAEncryption");
???????? cert = certGen.generateX509Certificate(priKey, "BC");
????? }catch (Exception e) {
???????? System.out.println(e.getClass() + e.getMessage());
????? }
????? try {
???????? return cert.getEncoded();
????? }catch (CertificateEncodingException e) {
???????? // TODO Auto-generated catch block
???????? e.printStackTrace();
???????? return null;
????? }
?? }
?? /**
?? ?*寫文件
?? ?*@param name
?? ?*@param data
?? ?*/
?? static public void writeFile(String name, byte[] data) {
????? if(data == null)
????? {
???????? return;
????? }
????? FileOutputStreamfop = null;
????? try {
???????? fop = new FileOutputStream(new File(name));
???????? fop.write(data);
???????? fop.close();
????? }catch (IOException e) {
???????? // TODO Auto-generated catch block
???????? e.printStackTrace();
????? }
?? }
?? public static void main(String[] args) {
????? // TODOAuto-generated method stub
????? byte[] crtBuf=generateCert();
????? if(crtBuf != null) {
???????? writeFile("./TestCrt.crt", crtBuf);
????? }
?? }
}
生成后的效果: