下面列出了怎么用java.security.spec.RSAPrivateCrtKeySpec的API类实例代码及写法,或者点击链接到github查看源代码。
private RSAPrivateCrtKeySpec parsePKCS1(byte[] source) {
Asn1Parser p = new Asn1Parser(source);
// https://en.wikipedia.org/wiki/X.690#BER_encoding
// https://tools.ietf.org/html/rfc8017#page-55
// Type
p.parseTag(0x30);
// Length
p.parseFullLength();
BigInteger version = p.parseInt();
if (version.intValue() == 1) {
// JRE doesn't provide a suitable constructor for multi-prime
// keys
throw new IllegalArgumentException(sm.getString("pemFile.noMultiPrimes"));
}
return new RSAPrivateCrtKeySpec(p.parseInt(), p.parseInt(), p.parseInt(), p.parseInt(),
p.parseInt(), p.parseInt(), p.parseInt(), p.parseInt());
}
private void readPrivateKeyPKCS1PEM(String privateKeyPath) throws IOException, NoSuchAlgorithmException,
InvalidKeySpecException {
String content = new String(
Files.readAllBytes(Paths.get(privateKeyPath)), Charset.forName("UTF-8"));
content = content.replaceAll("\\n", "").replace(START_RSA_PRIVATE_KEY, "")
.replace(END_RSA_PRIVATE_KEY, "");
byte[] bytes = Base64.getDecoder().decode(content);
DerInputStream derReader = new DerInputStream(bytes);
DerValue[] seq = derReader.getSequence(0);
// skip version seq[0];
BigInteger modulus = seq[1].getBigInteger();
BigInteger publicExp = seq[2].getBigInteger();
BigInteger privateExp = seq[3].getBigInteger();
BigInteger prime1 = seq[4].getBigInteger();
BigInteger prime2 = seq[5].getBigInteger();
BigInteger exp1 = seq[6].getBigInteger();
BigInteger exp2 = seq[7].getBigInteger();
BigInteger crtCoef = seq[8].getBigInteger();
RSAPrivateCrtKeySpec keySpec =
new RSAPrivateCrtKeySpec(modulus, publicExp, privateExp, prime1, prime2, exp1, exp2, crtCoef);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
privateKey = keyFactory.generatePrivate(keySpec);
}
public static final PrivateKey readRSAPrivateKeyFromDerEncodedBinaryData(final byte[] keyData) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
try(final ByteArrayInputStream bais = new ByteArrayInputStream(keyData)) {
try(final DerInputStream dis = new DerInputStream(bais)) {
dis.read(); // Skip header of DER structure
dis.readLength(); // Skip size of DER structure
/*final BigInteger version = */dis.readInteger(); // Skip version indicator
final BigInteger modulus = dis.readInteger();
final BigInteger publicExponent = dis.readInteger();
final BigInteger privateExponent = dis.readInteger();
final BigInteger prime1 = dis.readInteger();
final BigInteger prime2 = dis.readInteger();
final BigInteger exponent1 = dis.readInteger();
final BigInteger exponent2 = dis.readInteger();
final BigInteger coefficient = dis.readInteger();
final KeySpec keySpec = new RSAPrivateCrtKeySpec(modulus, publicExponent, privateExponent, prime1, prime2, exponent1, exponent2, coefficient);
final KeyFactory keyFactory = KeyFactory.getInstance("RSA");
final PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
}
}
private KeyPair createKeyPair() throws InvalidKeySpecException, NoSuchAlgorithmException {
final RSAKeyPairGenerator gen = new RSAKeyPairGenerator();
gen.init(new RSAKeyGenerationParameters(BigInteger.valueOf(3), new SecureRandom(), 1024, 80));
final AsymmetricCipherKeyPair keypair = gen.generateKeyPair();
final RSAKeyParameters publicKey = (RSAKeyParameters) keypair.getPublic();
final RSAPrivateCrtKeyParameters privateKey = (RSAPrivateCrtKeyParameters) keypair.getPrivate();
final PublicKey pubKey = KeyFactory.getInstance("RSA").generatePublic(
new RSAPublicKeySpec(publicKey.getModulus(), publicKey.getExponent()));
final PrivateKey privKey = KeyFactory.getInstance("RSA").generatePrivate(
new RSAPrivateCrtKeySpec(publicKey.getModulus(), publicKey.getExponent(),
privateKey.getExponent(), privateKey.getP(), privateKey.getQ(),
privateKey.getDP(), privateKey.getDQ(), privateKey.getQInv()));
return new KeyPair(pubKey, privKey);
}
private static PrivateKey toPrivateKey(String key)
throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
String content = key.replaceAll("\\n", "").replace(RsaPrivateKeyStart, "").replace(RsaPrivateKeyEnd, "");
byte[] bytes = Base64.getDecoder().decode(content);
DerInputStream derReader = new DerInputStream(bytes);
DerValue[] seq = derReader.getSequence(0);
// skip version seq[0];
BigInteger modulus = seq[1].getBigInteger();
BigInteger publicExp = seq[2].getBigInteger();
BigInteger privateExp = seq[3].getBigInteger();
BigInteger prime1 = seq[4].getBigInteger();
BigInteger prime2 = seq[5].getBigInteger();
BigInteger exp1 = seq[6].getBigInteger();
BigInteger exp2 = seq[7].getBigInteger();
BigInteger crtCoef = seq[8].getBigInteger();
RSAPrivateCrtKeySpec keySpec =
new RSAPrivateCrtKeySpec(modulus, publicExp, privateExp, prime1, prime2, exp1, exp2, crtCoef);
return keyFactory.generatePrivate(keySpec);
}
private PrivateKey getPrivateKey(String pem) throws GeneralSecurityException, IOException {
String pemContent = pem.replaceAll("\\n", "").replace("-----BEGIN RSA PRIVATE KEY-----", "").replace("-----END RSA PRIVATE KEY-----", "");
DerInputStream derReader = new DerInputStream(Base64.getDecoder().decode(pemContent));
DerValue[] seq = derReader.getSequence(0);
if (seq.length < 9) {
throw new GeneralSecurityException("Could not parse a PKCS1 private key.");
}
// skip version seq[0];
BigInteger modulus = seq[1].getBigInteger();
BigInteger publicExp = seq[2].getBigInteger();
BigInteger privateExp = seq[3].getBigInteger();
BigInteger prime1 = seq[4].getBigInteger();
BigInteger prime2 = seq[5].getBigInteger();
BigInteger exp1 = seq[6].getBigInteger();
BigInteger exp2 = seq[7].getBigInteger();
BigInteger crtCoef = seq[8].getBigInteger();
RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(modulus, publicExp, privateExp, prime1, prime2, exp1, exp2, crtCoef);
KeyFactory factory = KeyFactory.getInstance("RSA");
return factory.generatePrivate(keySpec);
}
public static RSAPrivateCrtKeySpec decodePKCS1(byte[] keyBytes) throws IOException {
DerParser parser = new DerParser(keyBytes);
Asn1Object sequence = parser.read();
sequence.validateSequence();
parser = new DerParser(sequence.getValue());
parser.read();
return new RSAPrivateCrtKeySpec(
next(parser),
next(parser),
next(parser),
next(parser),
next(parser),
next(parser),
next(parser),
next(parser));
}
private static PrivateKey toPrivateKey(String key)
throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
String content = key.replaceAll("\\n", "").replace(RsaPrivateKeyStart, "").replace(RsaPrivateKeyEnd, "");
byte[] bytes = Base64.getDecoder().decode(content);
DerInputStream derReader = new DerInputStream(bytes);
DerValue[] seq = derReader.getSequence(0);
// skip version seq[0];
BigInteger modulus = seq[1].getBigInteger();
BigInteger publicExp = seq[2].getBigInteger();
BigInteger privateExp = seq[3].getBigInteger();
BigInteger prime1 = seq[4].getBigInteger();
BigInteger prime2 = seq[5].getBigInteger();
BigInteger exp1 = seq[6].getBigInteger();
BigInteger exp2 = seq[7].getBigInteger();
BigInteger crtCoef = seq[8].getBigInteger();
RSAPrivateCrtKeySpec keySpec =
new RSAPrivateCrtKeySpec(modulus, publicExp, privateExp, prime1, prime2, exp1, exp2, crtCoef);
return keyFactory.generatePrivate(keySpec);
}
private static KeyPair getWellKnownKey() throws Exception {
BigInteger modulus = new BigInteger("27266783713040163753473734334021230592631652450892850648620119914958066181400432364213298181846462385257448168605902438305568194683691563208578540343969522651422088760509452879461613852042845039552547834002168737350264189810815735922734447830725099163869215360401162450008673869707774119785881115044406101346450911054819448375712432746968301739007624952483347278954755460152795801894283389540036131881712321193750961817346255102052653789197325341350920441746054233522546543768770643593655942246891652634114922277138937273034902434321431672058220631825053788262810480543541597284376261438324665363067125951152574540779");
BigInteger publicExponent = new BigInteger("65537");
BigInteger privateExponent = new BigInteger("10466613941269075477152428927796086150095892102279802916937552172064636326433780566497000814207416485739683286961848843255766652023400959086290344987308562817062506476465756840999981989957456897020361717197805192876094362315496459535960304928171129585813477132331538577519084006595335055487028872410579127692209642938724850603554885478763205394868103298473476811627231543504190652483290944218004086457805431824328448422034887148115990501701345535825110962804471270499590234116100216841170344686381902328362376624405803648588830575558058257742073963036264273582756620469659464278207233345784355220317478103481872995809");
BigInteger primeP = new BigInteger("175002941104568842715096339107566771592009112128184231961529953978142750732317724951747797764638217287618769007295505214923187971350518217670604044004381362495186864051394404165602744235299100790551775147322153206730562450301874236875459336154569893255570576967036237661594595803204808064127845257496057219227");
BigInteger primeQ = new BigInteger("155807574095269324897144428622185380283967159190626345335083690114147315509962698765044950001909553861571493035240542031420213144237033208612132704562174772894369053916729901982420535940939821673277140180113593951522522222348910536202664252481405241042414183668723338300649954708432681241621374644926879028977");
BigInteger primeExponentP = new BigInteger("79745606804504995938838168837578376593737280079895233277372027184693457251170125851946171360348440134236338520742068873132216695552312068793428432338173016914968041076503997528137698610601222912385953171485249299873377130717231063522112968474603281996190849604705284061306758152904594168593526874435238915345");
BigInteger primeExponentQ = new BigInteger("80619964983821018303966686284189517841976445905569830731617605558094658227540855971763115484608005874540349730961777634427740786642996065386667564038755340092176159839025706183161615488856833433976243963682074011475658804676349317075370362785860401437192843468423594688700132964854367053490737073471709030801");
BigInteger crtCoefficient = new BigInteger("2157818511040667226980891229484210846757728661751992467240662009652654684725325675037512595031058612950802328971801913498711880111052682274056041470625863586779333188842602381844572406517251106159327934511268610438516820278066686225397795046020275055545005189953702783748235257613991379770525910232674719428");
KeySpec publicKeySpec = new RSAPublicKeySpec(modulus, publicExponent);
KeySpec privateKeySpec = new RSAPrivateCrtKeySpec(modulus, publicExponent, privateExponent, primeP, primeQ, primeExponentP, primeExponentQ, crtCoefficient);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return new KeyPair(keyFactory.generatePublic(publicKeySpec), keyFactory.generatePrivate(privateKeySpec));
}
public static KeyStore createKeyStore(InputStream certInputStream, InputStream keyInputStream, String clientKeyAlgo, char[] clientKeyPassphrase) throws IOException, CertificateException, NoSuchAlgorithmException, InvalidKeySpecException, KeyStoreException {
CertificateFactory certFactory = CertificateFactory.getInstance("X509");
X509Certificate cert = (X509Certificate) certFactory.generateCertificate(certInputStream);
byte[] keyBytes = decodePem(keyInputStream);
PrivateKey privateKey;
KeyFactory keyFactory = KeyFactory.getInstance(clientKeyAlgo);
try {
// First let's try PKCS8
privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
} catch (InvalidKeySpecException e) {
// Otherwise try PKCS8
RSAPrivateCrtKeySpec keySpec = PKCS1Util.decodePKCS1(keyBytes);
privateKey = keyFactory.generatePrivate(keySpec);
}
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(null, clientKeyPassphrase);
String alias = cert.getSubjectX500Principal().getName();
keyStore.setKeyEntry(alias, privateKey, clientKeyPassphrase, new Certificate[]{cert});
return keyStore;
}
private PrivateKey extractPrivateKey(InputStream rawKey, char[] passphrase) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
try (InputStreamReader pemReader = new InputStreamReader(rawKey)) {
try (PEMParser pemParser = new PEMParser(pemReader)) {
Object pemObject = pemParser.readObject();
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
KeyPair keyPair;
if (pemObject instanceof PrivateKeyInfo) {
return converter.getPrivateKey((PrivateKeyInfo)pemObject);
}
if (pemObject instanceof PEMEncryptedKeyPair) {
PEMEncryptedKeyPair pemEncryptedKeyPair = (PEMEncryptedKeyPair) pemObject;
PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().build(passphrase);
keyPair = converter.getKeyPair(pemEncryptedKeyPair.decryptKeyPair(decProv));
} else {
keyPair = converter.getKeyPair((PEMKeyPair) pemObject);
}
KeyFactory keyFac = KeyFactory.getInstance("RSA");
RSAPrivateCrtKeySpec privateKeySpec = keyFac.getKeySpec(keyPair.getPrivate(), RSAPrivateCrtKeySpec.class);
return keyFac.generatePrivate(privateKeySpec);
}
}
}
private static RSAPrivateKey toJcaPrivateKey(
org.bouncycastle.asn1.pkcs.RSAPrivateKey rsaPrivateKey)
throws GeneralSecurityException {
RSAPrivateCrtKeySpec spec = new RSAPrivateCrtKeySpec(rsaPrivateKey.getModulus(),
rsaPrivateKey.getPublicExponent(),
rsaPrivateKey.getPrivateExponent(),
rsaPrivateKey.getPrime1(),
rsaPrivateKey.getPrime2(),
rsaPrivateKey.getExponent1(),
rsaPrivateKey.getExponent2(),
rsaPrivateKey.getCoefficient());
KeyFactory kf = KeyFactory.getInstance("RSA", "BC");
RSAPrivateKey privateKey = (RSAPrivateKey) kf.generatePrivate(spec);
return privateKey;
}
public Ssh2RsaPrivateCrtKey(BigInteger modulus, BigInteger publicExponent,
BigInteger privateExponent, BigInteger primeP, BigInteger primeQ,
BigInteger primeExponentP, BigInteger primeExponentQ,
BigInteger crtCoefficient) throws NoSuchAlgorithmException,
InvalidKeySpecException {
KeyFactory keyFactory = JCEProvider
.getProviderForAlgorithm(JCEAlgorithms.JCE_RSA) == null ? KeyFactory
.getInstance(JCEAlgorithms.JCE_RSA) : KeyFactory.getInstance(
JCEAlgorithms.JCE_RSA,
JCEProvider.getProviderForAlgorithm(JCEAlgorithms.JCE_RSA));
RSAPrivateCrtKeySpec spec = new RSAPrivateCrtKeySpec(modulus,
publicExponent, privateExponent, primeP, primeQ,
primeExponentP, primeExponentQ, crtCoefficient);
prv = (RSAPrivateCrtKey) keyFactory.generatePrivate(spec);
}
public static PrivateKey getPrivateKeyFromKeyPair(AsymmetricCipherKeyPair keyPair) throws Exception {
Security.addProvider(new BouncyCastleProvider());
RSAPrivateCrtKeyParameters privateKey = (RSAPrivateCrtKeyParameters)keyPair.getPrivate();
RSAKeyParameters publicKey = (RSAKeyParameters)keyPair.getPublic();
return KeyFactory.getInstance("RSA").generatePrivate(
new RSAPrivateCrtKeySpec(privateKey.getModulus(), publicKey.getExponent(), privateKey.getExponent(), privateKey.getP(), privateKey.getQ(), privateKey.getDP(), privateKey.getDQ(),
privateKey.getQInv()));
}
/**
* construct a private key from an RSAPrivateCrtKeySpec
*
* @param spec the spec to be used in construction.
*/
JCERSAPrivateCrtKey(
RSAPrivateCrtKeySpec spec)
{
this.modulus = spec.getModulus();
this.publicExponent = spec.getPublicExponent();
this.privateExponent = spec.getPrivateExponent();
this.primeP = spec.getPrimeP();
this.primeQ = spec.getPrimeQ();
this.primeExponentP = spec.getPrimeExponentP();
this.primeExponentQ = spec.getPrimeExponentQ();
this.crtCoefficient = spec.getCrtCoefficient();
}
/**
* Decode PKCS#1 encoded private key into RSAPrivateCrtKeySpec.
*
* <p/>The ASN.1 syntax for the private key with CRT is
*
* <pre>
* --
* -- Representation of RSA private key with information for the CRT algorithm.
* --
* 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
* }
* </pre>
*
* @param keyBytes PKCS#1 encoded key
* @throws IOException
*/
private void decode(byte[] keyBytes) throws IOException {
DerParser parser = new DerParser(keyBytes);
Asn1Object sequence = parser.read();
if (sequence.getType() != DerParser.SEQUENCE)
throw new IOException("Invalid DER: not a sequence"); //$NON-NLS-1$
// Parse inside the sequence
parser = sequence.getParser();
parser.read(); // Skip version
BigInteger modulus = parser.read().getInteger();
BigInteger publicExp = parser.read().getInteger();
BigInteger privateExp = parser.read().getInteger();
BigInteger prime1 = parser.read().getInteger();
BigInteger prime2 = parser.read().getInteger();
BigInteger exp1 = parser.read().getInteger();
BigInteger exp2 = parser.read().getInteger();
BigInteger crtCoef = parser.read().getInteger();
keySpec = new RSAPrivateCrtKeySpec(
modulus, publicExp, privateExp, prime1, prime2,
exp1, exp2, crtCoef);
}
public static PrivateKey getPrivateKey(String priKeyData) throws Exception {
/*
* n:512 e:512 d:512 p:256 q:256 dmp1:256 dmq1:256 iqmp:256
*/
BigInteger modulus = new BigInteger(priKeyData.substring(8, 512 + 8),
16);
BigInteger publicExponent = new BigInteger(priKeyData.substring(
512 + 8, 512 + 8 + 512), 16);
BigInteger privateExponent = new BigInteger(priKeyData.substring(
512 + 8 + 512, 512 + 8 + 512 + 512), 16);
BigInteger primeP = new BigInteger(priKeyData.substring(
512 + 8 + 512 + 512, 512 + 8 + 512 + 512 + 256), 16);
BigInteger primeQ = new BigInteger(priKeyData.substring(512 + 8 + 512
+ 512 + 256, 512 + 8 + 512 + 512 + 256 + 256), 16);
BigInteger primeExponentP = new BigInteger(
priKeyData.substring(512 + 8 + 512 + 512 + 256 + 256, 512 + 8
+ 512 + 512 + 256 + 256 + 256), 16);
BigInteger primeExponentQ = new BigInteger(priKeyData.substring(512 + 8
+ 512 + 512 + 256 + 256 + 256, 512 + 8 + 512 + 512 + 256 + 256
+ 256 + 256), 16);
BigInteger crtCoefficient = new BigInteger(priKeyData.substring(512 + 8
+ 512 + 512 + 256 + 256 + 256 + 256, 512 + 8 + 512 + 512 + 256
+ 256 + 256 + 256 + 256), 16);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPrivateCrtKeySpec rsaPrivateKeySpec = new RSAPrivateCrtKeySpec(
modulus, publicExponent, privateExponent, primeP, primeQ,
primeExponentP, primeExponentQ, crtCoefficient);
return keyFactory.generatePrivate(rsaPrivateKeySpec);
}
public void bad10() throws Exception {
BigInteger bigInteger = new BigInteger("12345", 5);
new DSAPrivateKeySpec(bigInteger, null, null, null);
new DSAPublicKeySpec(bigInteger, null, bigInteger, null); // report once
new DHPrivateKeySpec(bigInteger, null, null);
new DHPublicKeySpec(bigInteger, null, null);
new ECPrivateKeySpec(bigInteger, null);
new RSAPrivateKeySpec(bigInteger, null);
new RSAMultiPrimePrivateCrtKeySpec(bigInteger, null, null, null, null, null, null, null, null);
new RSAPrivateCrtKeySpec(bigInteger, null, null, null, null, null, null, null);
new RSAPublicKeySpec(bigInteger, null);
new DSAPublicKeyImpl(bigInteger, null, null, null);
}
private static RSAPrivateCrtKeySpec getRSAKeySpec(byte[] keyBytes) throws InvalidKeySpecException
{
ByteBuffer buffer = ByteBuffer.wrap(keyBytes);
try
{
// PKCS#1 is encoded as a DER sequence of:
// (version, modulus, publicExponent, privateExponent, primeP, primeQ,
// primeExponentP, primeExponentQ, crtCoefficient)
int tag = ((int)buffer.get()) & 0xff;
// check tag is that of a sequence
if(((tag & 0x20) != 0x20) || ((tag & 0x1F) != 0x10))
{
throw new InvalidKeySpecException("Unable to parse key as PKCS#1 format");
}
int length = getLength(buffer);
buffer = buffer.slice();
buffer.limit(length);
// first tlv is version - which we'll ignore
byte versionTag = buffer.get();
int versionLength = getLength(buffer);
buffer.position(buffer.position()+versionLength);
RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(
getInteger(buffer), getInteger(buffer), getInteger(buffer), getInteger(buffer), getInteger(buffer),
getInteger(buffer), getInteger(buffer), getInteger(buffer));
return keySpec;
}
catch(BufferUnderflowException e)
{
throw new InvalidKeySpecException("Unable to parse key as PKCS#1 format");
}
}
public static RSAPrivateCrtKeySpec decodePKCS1(byte[] keyBytes) throws IOException {
DerParser parser = new DerParser(keyBytes);
Asn1Object sequence = parser.read();
sequence.validateSequence();
parser = new DerParser(sequence.getValue());
parser.read();
return new RSAPrivateCrtKeySpec(next(parser), next(parser),
next(parser), next(parser),
next(parser), next(parser),
next(parser), next(parser));
}
/**
* Retrieve a {@link RSAPrivateCrtKeySpec}.
* @return the {@link RSAPrivateCrtKeySpec}.
* @since 2.3
*/
public RSAPrivateCrtKeySpec getRSAPrivateKeySpec() {
if (!isPrivateKey()) {
throw new IllegalStateException("PEM object is not a private key");
}
try {
return KeystoreUtil.getRSAPrivateKeySpec(this.content);
}
catch (IOException e) {
throw new IllegalStateException("Cannot obtain PrivateKey", e);
}
}
@Test
void keysShouldMatch() throws IOException {
PemObject publicKey = PemObject.parseFirst(
new String(FileCopyUtils.copyToByteArray(new File(this.privateDir, "localhost.public.key.pem"))));
PemObject privateKey = PemObject.parseFirst(
new String(FileCopyUtils.copyToByteArray(new File(this.privateDir, "localhost.decrypted.key.pem"))));
RSAPublicKeySpec publicSpec = publicKey.getRSAPublicKeySpec();
RSAPrivateCrtKeySpec privateKeySpec = privateKey.getRSAPrivateKeySpec();
assertThat(publicSpec.getModulus()).isEqualTo(privateKeySpec.getModulus());
assertThat(publicSpec.getPublicExponent()).isEqualTo(privateKeySpec.getPublicExponent());
}
private PEM decode_PKCS_1_Private(String encodedKey) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
byte[] bytes = getKeyBytes(encodedKey, PKCS_1_PRIVATE_KEY_PREFIX, PKCS_1_PRIVATE_KEY_SUFFIX);
DerValue[] sequence = new DerInputStream(bytes).getSequence();
// DER Encoded PKCS#1 structure
// https://tools.ietf.org/html/rfc3447#appendix-A.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
// }
if (sequence.length < 9) {
throw new PEMDecoderException(
new InvalidKeyException("Could not build a PKCS#1 private key. Expected at least 9 values in the DER encoded sequence."));
}
// Ignoring the version value in the sequence
BigInteger n = sequence[1].getBigInteger();
BigInteger e = sequence[2].getBigInteger();
BigInteger d = sequence[3].getBigInteger();
BigInteger p = sequence[4].getBigInteger();
BigInteger q = sequence[5].getBigInteger();
BigInteger d_mod_p1 = sequence[6].getBigInteger();
BigInteger d_mod_q1 = sequence[7].getBigInteger();
BigInteger mod_p = sequence[8].getBigInteger();
PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(new RSAPrivateCrtKeySpec(n, e, d, p, q, d_mod_p1, d_mod_q1, mod_p));
PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(n, e));
return new PEM(privateKey, publicKey);
}
private static KeyManager[] configureClientCert(String clientCertFile, String clientKeyFile, char[] clientKeyPassword, String clientKeyAlgo) throws Exception {
try {
InputStream certInputStream = openFile(clientCertFile);
CertificateFactory certFactory = CertificateFactory.getInstance("X509");
X509Certificate cert = (X509Certificate)certFactory.generateCertificate(certInputStream);
InputStream keyInputStream = openFile(clientKeyFile);
PEMReader reader = new PEMReader(keyInputStream);
RSAPrivateCrtKeySpec keySpec = new PKCS1EncodedKeySpec(reader.getDerBytes()).getKeySpec();
KeyFactory kf = KeyFactory.getInstance(clientKeyAlgo);
RSAPrivateKey privKey = (RSAPrivateKey)kf.generatePrivate(keySpec);
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(null);
String alias = cert.getSubjectX500Principal().getName();
keyStore.setKeyEntry(alias, privKey, clientKeyPassword, new Certificate[]{cert});
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, clientKeyPassword);
return keyManagerFactory.getKeyManagers();
} catch (Exception e) {
log.log(Level.SEVERE, "Could not create key manager for " + clientCertFile + " (" + clientKeyFile + ")", e);
throw e;
}
}
/**
* Decode PKCS#1 encoded private key into RSAPrivateCrtKeySpec.
*
* <p/>The ASN.1 syntax for the private key with CRT is
*
* <pre>
* --
* -- Representation of RSA private key with information for the CRT algorithm.
* --
* 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
* }
* </pre>
*
* @param keyBytes PKCS#1 encoded key
* @throws IOException
*/
private void decode(byte[] keyBytes) throws IOException {
DerParser parser = new DerParser(keyBytes);
Asn1Object sequence = parser.read();
if (sequence.getType() != DerParser.SEQUENCE)
throw new IOException("Invalid DER: not a sequence"); //$NON-NLS-1$
// Parse inside the sequence
parser = sequence.getParser();
parser.read(); // Skip version
BigInteger modulus = parser.read().getInteger();
BigInteger publicExp = parser.read().getInteger();
BigInteger privateExp = parser.read().getInteger();
BigInteger prime1 = parser.read().getInteger();
BigInteger prime2 = parser.read().getInteger();
BigInteger exp1 = parser.read().getInteger();
BigInteger exp2 = parser.read().getInteger();
BigInteger crtCoef = parser.read().getInteger();
keySpec = new RSAPrivateCrtKeySpec(
modulus, publicExp, privateExp, prime1, prime2,
exp1, exp2, crtCoef);
}
public RSAPrivateKey privateKey(BigInteger modulus, BigInteger publicExponent, BigInteger privateExponent, BigInteger primeP,
BigInteger primeQ, BigInteger primeExponentP, BigInteger primeExponentQ,
BigInteger crtCoefficient) throws JoseException
{
RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(modulus,
publicExponent, privateExponent, primeP, primeQ, primeExponentP, primeExponentQ, crtCoefficient);
return getRsaPrivateKey(keySpec);
}
protected PrivateKey engineGeneratePrivate(
KeySpec keySpec)
throws InvalidKeySpecException
{
if (keySpec instanceof PKCS8EncodedKeySpec)
{
try
{
return generatePrivate(PrivateKeyInfo.getInstance(((PKCS8EncodedKeySpec)keySpec).getEncoded()));
}
catch (Exception e)
{
//
// in case it's just a RSAPrivateKey object... -- openSSL produces these
//
try
{
return new BCRSAPrivateCrtKey(
RSAPrivateKey.getInstance(((PKCS8EncodedKeySpec)keySpec).getEncoded()));
}
catch (Exception ex)
{
throw new ExtendedInvalidKeySpecException("unable to process key spec: " + e.toString(), e);
}
}
}
else if (keySpec instanceof RSAPrivateCrtKeySpec)
{
return new BCRSAPrivateCrtKey((RSAPrivateCrtKeySpec)keySpec);
}
else if (keySpec instanceof RSAPrivateKeySpec)
{
return new BCRSAPrivateKey((RSAPrivateKeySpec)keySpec);
}
throw new InvalidKeySpecException("Unknown KeySpec type: " + keySpec.getClass().getName());
}
/**
* construct a private key from an RSAPrivateCrtKeySpec
*
* @param spec the spec to be used in construction.
*/
BCRSAPrivateCrtKey(
RSAPrivateCrtKeySpec spec)
{
this.modulus = spec.getModulus();
this.publicExponent = spec.getPublicExponent();
this.privateExponent = spec.getPrivateExponent();
this.primeP = spec.getPrimeP();
this.primeQ = spec.getPrimeQ();
this.primeExponentP = spec.getPrimeExponentP();
this.primeExponentQ = spec.getPrimeExponentQ();
this.crtCoefficient = spec.getCrtCoefficient();
}
private KeyManager[] configureClientCert(String clientCertFile, String clientKeyFile, char[] clientKeyPassword, String clientKeyAlgo) throws Exception {
try {
InputStream certInputStream = openFile(clientCertFile);
CertificateFactory certFactory = CertificateFactory.getInstance("X509");
X509Certificate cert = (X509Certificate)certFactory.generateCertificate(certInputStream);
InputStream keyInputStream = openFile(clientKeyFile);
PEMReader reader = new PEMReader(keyInputStream);
RSAPrivateCrtKeySpec keySpec = new PKCS1EncodedKeySpec(reader.getDerBytes()).getKeySpec();
KeyFactory kf = KeyFactory.getInstance(clientKeyAlgo);
RSAPrivateKey privKey = (RSAPrivateKey)kf.generatePrivate(keySpec);
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(null);
String alias = cert.getSubjectX500Principal().getName();
keyStore.setKeyEntry(alias, privKey, clientKeyPassword, new Certificate[]{cert});
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, clientKeyPassword);
return keyManagerFactory.getKeyManagers();
} catch (Exception e) {
log.log(Level.SEVERE, "Could not create key manager for " + clientCertFile + " (" + clientKeyFile + ")", e);
throw e;
}
}
/**
* Decode PKCS#1 encoded private key into RSAPrivateCrtKeySpec.
*
* <p/>The ASN.1 syntax for the private key with CRT is
*
* <pre>
* --
* -- Representation of RSA private key with information for the CRT algorithm.
* --
* 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
* }
* </pre>
*
* @param keyBytes PKCS#1 encoded key
* @throws IOException
*/
private void decode(byte[] keyBytes) throws IOException {
DerParser parser = new DerParser(keyBytes);
Asn1Object sequence = parser.read();
if (sequence.getType() != DerParser.SEQUENCE)
throw new IOException("Invalid DER: not a sequence"); //$NON-NLS-1$
// Parse inside the sequence
parser = sequence.getParser();
parser.read(); // Skip version
BigInteger modulus = parser.read().getInteger();
BigInteger publicExp = parser.read().getInteger();
BigInteger privateExp = parser.read().getInteger();
BigInteger prime1 = parser.read().getInteger();
BigInteger prime2 = parser.read().getInteger();
BigInteger exp1 = parser.read().getInteger();
BigInteger exp2 = parser.read().getInteger();
BigInteger crtCoef = parser.read().getInteger();
keySpec = new RSAPrivateCrtKeySpec(
modulus, publicExp, privateExp, prime1, prime2,
exp1, exp2, crtCoef);
}