📄 rsakeyfactory.java
字号:
package au.net.aba.crypto.provider;
/*
* $Id: RSAKeyFactory.java,v 1.13 1999/02/17 01:40:52 leachbj Exp $
* $Author: leachbj $
*
* Copyright (C) 1996-1998 Australian Business Access Pty Ltd.
* All rights reserved.
*
* Use, modification, copying and distribution of this software is subject the
* terms and conditions of the ABA Public Licence. See the file
* "PUBLIC_LICENCE" for additional information.
*
* If you have not received a copy of the Public Licence, you must destroy all
* copies of this file immediately.
*
* $Source: /aba/CVSROOT/jdk1.1/src/au.net.aba/crypto/provider/RSAKeyFactory.java,v $
* $Revision: 1.13 $
* $Date: 1999/02/17 01:40:52 $
* $State: Exp $
*/
import java.security.*;
import java.security.KeyFactorySpi;
import java.security.spec.*;
import java.security.interfaces.*;
import au.net.aba.crypto.spec.AsciiEncodedKeySpec;
import java.io.PrintStream;
import java.math.BigInteger;
import java.util.StringTokenizer;
/**
* This class is used to convert RSA keys into a format usable by the
* ABA provider. Currently this class can convert from a KeySpec
* into a Key, or from one of the standard RSA Key interfaces into
* an ABA key.
* <p>
* The supported KeySpec classes are AsciiEncodedKeySpec,
* RSAPrivateCrtKeySpec, RSAPublicKeySpec, X509EncodedKeySpec and
* PKCS8EncodedKeySpec.
* <p>
* The supported RSA Key interfaces are RSAPublicKey, RSAPrivateKey
* and RSAPrivateCrtKey.
* <p>
* This class should not be instantiated directly, instead use the
* java.security.KeyFactory interface.
*
* @see java.security.KeyFactory
* @see java.security.interfaces.RSAPublicKey;
* @see java.security.interfaces.RSAPrivateKey;
* @see java.security.spec.RSAPrivateKeySpec;
* @see java.security.spec.RSAPublicKeySpec;
* @see java.security.spec.X509EncodedKeySpec;
* @see java.security.spec.PKCS8EncodedKeySpec;
* @see au.net.aba.crypto.spec.AsciiEncodedKeySpec;
*/
public class RSAKeyFactory extends KeyFactorySpi
{
public final static String ident = "$Id: RSAKeyFactory.java,v 1.13 1999/02/17 01:40:52 leachbj Exp $";
/**
* Generates a private key object from the provided key specification
* (key material). This class supports the AsciiEncodedKeySpec,
* RSAPrivateKeySpec, RSAPrivateCrtKeySpec and PKCS8Encoded KeySpec
* classes.
*
* @returns The private key.
* @exception InvalidKeySpecException The provided KeySpec was not
* an AsciiEncodedKeySpec, RSAPrivateKeySpec, RSAPrivateCrtKeySpec
* or PKCS8EncodedKeySpec KeySpec instance.
*/
protected PrivateKey engineGeneratePrivate(
KeySpec keySpec)
throws InvalidKeySpecException
{
if (keySpec instanceof AsciiEncodedKeySpec)
{
/*
* Convert the AsciiEncodedKeySpec into
* a RSAPrivateCrtKeySpec
*/
BigInteger bigInts[] = parseKey(
((AsciiEncodedKeySpec)keySpec).getEncoded());
if (bigInts.length == 8)
{
return new RSAPrivKeyCrt(
bigInts[0], // modulus
bigInts[1], // publicExponent
bigInts[2], // privateExponent
bigInts[3], // primeP
bigInts[4], // primeQ
bigInts[5], // dP
bigInts[6], // dQ
bigInts[7]); // qInv
}
else
{
return new RSAPrivKey(
bigInts[0], // modulus
bigInts[1]); // privateExponent
}
}
else if (keySpec instanceof PKCS8EncodedKeySpec)
{
return new RSAPrivKeyCrt(
((PKCS8EncodedKeySpec)keySpec).getEncoded());
}
else if (keySpec instanceof RSAPrivateCrtKeySpec)
{
RSAPrivateCrtKeySpec rsaKeySpec =
(RSAPrivateCrtKeySpec)keySpec;
return new RSAPrivKeyCrt(
rsaKeySpec.getModulus(),
rsaKeySpec.getPublicExponent(),
rsaKeySpec.getPrivateExponent(),
rsaKeySpec.getPrimeP(),
rsaKeySpec.getPrimeQ(),
rsaKeySpec.getPrimeExponentP(),
rsaKeySpec.getPrimeExponentQ(),
rsaKeySpec.getCrtCoefficient());
}
else if (keySpec instanceof RSAPrivateKeySpec)
{
RSAPrivateKeySpec rsaKeySpec =
(RSAPrivateKeySpec)keySpec;
return new RSAPrivKey(rsaKeySpec.getModulus(),
rsaKeySpec.getPrivateExponent());
}
throw new InvalidKeySpecException("Unknown KeySpec type.");
}
/**
* Generates a public key object from the provided key specification
* (key material). This class supports the AsciiEncodedKeySpec,
* RSAPublicKeySpec and X509EncodedKeySpec KeySpec classes.
*
* @returns The public key.
* @exception InvalidKeySpecException The provided KeySpec was not
* an AsciiEncodedKeySpec, RSAPublicKeySpec or X509EncodedKeySpec
* KeySpec.
*/
protected PublicKey engineGeneratePublic(
KeySpec keySpec)
throws InvalidKeySpecException
{
if (keySpec instanceof AsciiEncodedKeySpec)
{
/*
* Convert the AsciiKeySpec directly into a RSA
* Public key.
*/
BigInteger bigInts[] = parseKey(
((AsciiEncodedKeySpec)keySpec).getEncoded());
if (bigInts.length >= 2)
{
return new RSAPubKey(
bigInts[0], // modulus
bigInts[1]); // publicExp
}
else
{
throw new InvalidKeySpecException(
"Incomplete EncodedKeySpec.");
}
}
else if (keySpec instanceof X509EncodedKeySpec)
{
return new RSAPubKey(
((X509EncodedKeySpec)keySpec).getEncoded());
}
else if (keySpec instanceof RSAPublicKeySpec)
{
RSAPublicKeySpec spec = (RSAPublicKeySpec)keySpec;
return new RSAPubKey(
spec.getModulus(),
spec.getPublicExponent());
}
throw new InvalidKeySpecException("Unknown KeySpec type.");
}
/**
* Returns a specification (key material) of the given key object.
* keySpec identifies the specification class in which the key material
* should be returned. It could, for example, be RSAPublicKeySpec.class,
* to indicate that the key material should be returned in an instance
* of the RSAPublicKeySpec class.
* <p>
* Currently supports standard RSA keys and RSAPublicKeySpec,
* RSAPrivateKeySpec, RSAPrivateCrtKeySpec, X509EncodedKeySpec
* and PKCS8EncodedKeySpec KeySpec classes.
*
* @param key the key the key material is to be recovered from.
* @param spec the class the new key spec object is meant to be from.
* @return the new key spec object representing the key material in key.
*/
protected KeySpec engineGetKeySpec(
Key key,
Class spec)
throws InvalidKeySpecException
{
if (key instanceof RSAPublicKey)
{
if (X509EncodedKeySpec.class.isAssignableFrom(spec))
{
return new X509EncodedKeySpec(
((X509EncodedKeySpec)key).getEncoded());
}
else if (RSAPublicKeySpec.class.isAssignableFrom(spec))
{
RSAPublicKey pubKey = (RSAPublicKey)key;
return new RSAPublicKeySpec(pubKey.getModulus(),
pubKey.getPublicExponent());
}
}
else if (key instanceof RSAPrivateKey)
{
if (PKCS8EncodedKeySpec.class.isAssignableFrom(spec))
{
return new PKCS8EncodedKeySpec(
((PKCS8EncodedKeySpec)key).getEncoded());
}
else if (RSAPrivateCrtKeySpec.class.isAssignableFrom(spec))
{
RSAPrivKeyCrt privKey = (RSAPrivKeyCrt)key;
return new RSAPrivateCrtKeySpec(
privKey.getModulus(),
privKey.getPublicExponent(),
privKey.getPrivateExponent(),
privKey.getPrimeP(),
privKey.getPrimeQ(),
privKey.getPrimeExponentP(),
privKey.getPrimeExponentQ(),
privKey.getCrtCoefficient());
}
else if (RSAPrivateKeySpec.class.isAssignableFrom(spec))
{
RSAPrivateKey privKey = (RSAPrivateKey)key;
return new RSAPrivateKeySpec(
privKey.getModulus(),
privKey.getPrivateExponent());
}
}
throw new InvalidKeySpecException("Invalid KeySpec.");
}
/**
* Translates a key object, whose provider may be unknown or
* potentially untrusted, into a corresponding key object of this key
* factory.
* <p>
* This KeyFactory will convert any key that implements either
* RSAPrivateCrtKey, RSAPrivateKey, or the RSAPublicKey interface.
*
* @param key the key to be translated.
* @return the same key, only for this provider.
*/
protected Key engineTranslateKey(
Key key)
throws InvalidKeyException
{
if (key instanceof RSAPrivateCrtKey)
{
if (key instanceof RSAPrivKeyCrt)
{
return key;
}
RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key;
return new RSAPrivKeyCrt(
rsaKey.getModulus(),
rsaKey.getPublicExponent(),
rsaKey.getPrivateExponent(),
rsaKey.getPrimeP(),
rsaKey.getPrimeQ(),
rsaKey.getPrimeExponentP(),
rsaKey.getPrimeExponentQ(),
rsaKey.getCrtCoefficient());
}
else if (key instanceof RSAPrivateKey)
{
if (key instanceof RSAPrivateKey)
{
return key;
}
RSAPrivateKey rsaKey = (RSAPrivateKey)key;
return new RSAPrivKey(
rsaKey.getModulus(),
rsaKey.getPrivateExponent());
}
else if (key instanceof RSAPublicKey)
{
if (key instanceof RSAPublicKey)
{
return key;
}
RSAPublicKey rsaKey = (RSAPublicKey)key;
return new RSAPubKey(
rsaKey.getModulus(),
rsaKey.getPublicExponent());
}
else
{
throw new InvalidKeyException("Unsupported key type.");
}
}
/**
* Parse a key from the ABA/PGP format into an array of
* BigIntegers. The format is:
* <pre>
* modulus.publicExp.privateExp.p.q
* </pre>
* @param keyBytes an ASCII string describing the key.
* @return an array of BigIntegers that make up the key.
*/
protected static BigInteger[] parseKey(
byte[] keyBytes)
{
String s = new String(keyBytes);
StringTokenizer st = new StringTokenizer(s, ".");
BigInteger[] bigInts;
int size = st.countTokens();
if (size > 2)
{
bigInts = new BigInteger[8];
}
else
{
bigInts = new BigInteger[2];
}
for (int i = 0; i != size; i++)
{
bigInts[i] = new BigInteger(st.nextToken(), 16);
}
if (size > 2)
{
BigInteger privateExponent;
BigInteger primeP, primeQ, pMinus1, qMinus1;
privateExponent = bigInts[2];
primeP = bigInts[3];
primeQ = bigInts[4];
/*
* ensure that p is the larger of the two primes
*/
if (primeP.compareTo(primeQ) < 0)
{
BigInteger temp;
temp = primeP;
bigInts[3] = primeP = primeQ;
bigInts[4] = primeQ = temp;
}
pMinus1 = primeP.subtract(BigInteger.valueOf(1));
qMinus1 = primeQ.subtract(BigInteger.valueOf(1));
bigInts[5] = privateExponent.remainder(pMinus1);
bigInts[6] = privateExponent.remainder(qMinus1);
bigInts[7] = primeQ.modInverse(primeP);
}
return bigInts;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -