1 package org.bouncycastle.jcajce.provider.asymmetric.rsa; 2 3 import java.io.IOException; 4 import java.math.BigInteger; 5 import java.security.interfaces.RSAPrivateCrtKey; 6 import java.security.spec.RSAPrivateCrtKeySpec; 7 8 import org.bouncycastle.asn1.DERNull; 9 import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; 10 import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; 11 import org.bouncycastle.asn1.pkcs.RSAPrivateKey; 12 import org.bouncycastle.asn1.x509.AlgorithmIdentifier; 13 import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; 14 import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; 15 import org.bouncycastle.util.Strings; 16 17 /** 18 * A provider representation for a RSA private key, with CRT factors included. 19 */ 20 public class BCRSAPrivateCrtKey 21 extends BCRSAPrivateKey 22 implements RSAPrivateCrtKey 23 { 24 static final long serialVersionUID = 7834723820638524718L; 25 26 private BigInteger publicExponent; 27 private BigInteger primeP; 28 private BigInteger primeQ; 29 private BigInteger primeExponentP; 30 private BigInteger primeExponentQ; 31 private BigInteger crtCoefficient; 32 33 /** 34 * construct a private key from it's org.bouncycastle.crypto equivalent. 35 * 36 * @param key the parameters object representing the private key. 37 */ 38 BCRSAPrivateCrtKey( 39 RSAPrivateCrtKeyParameters key) 40 { 41 super(key); 42 43 this.publicExponent = key.getPublicExponent(); 44 this.primeP = key.getP(); 45 this.primeQ = key.getQ(); 46 this.primeExponentP = key.getDP(); 47 this.primeExponentQ = key.getDQ(); 48 this.crtCoefficient = key.getQInv(); 49 } 50 51 /** 52 * construct a private key from an RSAPrivateCrtKeySpec 53 * 54 * @param spec the spec to be used in construction. 55 */ 56 BCRSAPrivateCrtKey( 57 RSAPrivateCrtKeySpec spec) 58 { 59 this.modulus = spec.getModulus(); 60 this.publicExponent = spec.getPublicExponent(); 61 this.privateExponent = spec.getPrivateExponent(); 62 this.primeP = spec.getPrimeP(); 63 this.primeQ = spec.getPrimeQ(); 64 this.primeExponentP = spec.getPrimeExponentP(); 65 this.primeExponentQ = spec.getPrimeExponentQ(); 66 this.crtCoefficient = spec.getCrtCoefficient(); 67 } 68 69 /** 70 * construct a private key from another RSAPrivateCrtKey. 71 * 72 * @param key the object implementing the RSAPrivateCrtKey interface. 73 */ 74 BCRSAPrivateCrtKey( 75 RSAPrivateCrtKey key) 76 { 77 this.modulus = key.getModulus(); 78 this.publicExponent = key.getPublicExponent(); 79 this.privateExponent = key.getPrivateExponent(); 80 this.primeP = key.getPrimeP(); 81 this.primeQ = key.getPrimeQ(); 82 this.primeExponentP = key.getPrimeExponentP(); 83 this.primeExponentQ = key.getPrimeExponentQ(); 84 this.crtCoefficient = key.getCrtCoefficient(); 85 } 86 87 /** 88 * construct an RSA key from a private key info object. 89 */ 90 BCRSAPrivateCrtKey( 91 PrivateKeyInfo info) 92 throws IOException 93 { 94 this(RSAPrivateKey.getInstance(info.parsePrivateKey())); 95 } 96 97 /** 98 * construct an RSA key from a ASN.1 RSA private key object. 99 */ 100 BCRSAPrivateCrtKey( 101 RSAPrivateKey key) 102 { 103 this.modulus = key.getModulus(); 104 this.publicExponent = key.getPublicExponent(); 105 this.privateExponent = key.getPrivateExponent(); 106 this.primeP = key.getPrime1(); 107 this.primeQ = key.getPrime2(); 108 this.primeExponentP = key.getExponent1(); 109 this.primeExponentQ = key.getExponent2(); 110 this.crtCoefficient = key.getCoefficient(); 111 } 112 113 /** 114 * return the encoding format we produce in getEncoded(). 115 * 116 * @return the encoding format we produce in getEncoded(). 117 */ 118 public String getFormat() 119 { 120 return "PKCS#8"; 121 } 122 123 /** 124 * Return a PKCS8 representation of the key. The sequence returned 125 * represents a full PrivateKeyInfo object. 126 * 127 * @return a PKCS8 representation of the key. 128 */ 129 public byte[] getEncoded() 130 { 131 return KeyUtil.getEncodedPrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPrivateKey(getModulus(), getPublicExponent(), getPrivateExponent(), getPrimeP(), getPrimeQ(), getPrimeExponentP(), getPrimeExponentQ(), getCrtCoefficient())); 132 } 133 134 /** 135 * return the public exponent. 136 * 137 * @return the public exponent. 138 */ 139 public BigInteger getPublicExponent() 140 { 141 return publicExponent; 142 } 143 144 /** 145 * return the prime P. 146 * 147 * @return the prime P. 148 */ 149 public BigInteger getPrimeP() 150 { 151 return primeP; 152 } 153 154 /** 155 * return the prime Q. 156 * 157 * @return the prime Q. 158 */ 159 public BigInteger getPrimeQ() 160 { 161 return primeQ; 162 } 163 164 /** 165 * return the prime exponent for P. 166 * 167 * @return the prime exponent for P. 168 */ 169 public BigInteger getPrimeExponentP() 170 { 171 return primeExponentP; 172 } 173 174 /** 175 * return the prime exponent for Q. 176 * 177 * @return the prime exponent for Q. 178 */ 179 public BigInteger getPrimeExponentQ() 180 { 181 return primeExponentQ; 182 } 183 184 /** 185 * return the CRT coefficient. 186 * 187 * @return the CRT coefficient. 188 */ 189 public BigInteger getCrtCoefficient() 190 { 191 return crtCoefficient; 192 } 193 194 public int hashCode() 195 { 196 return this.getModulus().hashCode() 197 ^ this.getPublicExponent().hashCode() 198 ^ this.getPrivateExponent().hashCode(); 199 } 200 201 public boolean equals(Object o) 202 { 203 if (o == this) 204 { 205 return true; 206 } 207 208 if (!(o instanceof RSAPrivateCrtKey)) 209 { 210 return false; 211 } 212 213 RSAPrivateCrtKey key = (RSAPrivateCrtKey)o; 214 215 return this.getModulus().equals(key.getModulus()) 216 && this.getPublicExponent().equals(key.getPublicExponent()) 217 && this.getPrivateExponent().equals(key.getPrivateExponent()) 218 && this.getPrimeP().equals(key.getPrimeP()) 219 && this.getPrimeQ().equals(key.getPrimeQ()) 220 && this.getPrimeExponentP().equals(key.getPrimeExponentP()) 221 && this.getPrimeExponentQ().equals(key.getPrimeExponentQ()) 222 && this.getCrtCoefficient().equals(key.getCrtCoefficient()); 223 } 224 225 public String toString() 226 { 227 StringBuffer buf = new StringBuffer(); 228 String nl = Strings.lineSeparator(); 229 230 buf.append("RSA Private CRT Key").append(nl); 231 buf.append(" modulus: ").append(this.getModulus().toString(16)).append(nl); 232 buf.append(" public exponent: ").append(this.getPublicExponent().toString(16)).append(nl); 233 buf.append(" private exponent: ").append(this.getPrivateExponent().toString(16)).append(nl); 234 buf.append(" primeP: ").append(this.getPrimeP().toString(16)).append(nl); 235 buf.append(" primeQ: ").append(this.getPrimeQ().toString(16)).append(nl); 236 buf.append(" primeExponentP: ").append(this.getPrimeExponentP().toString(16)).append(nl); 237 buf.append(" primeExponentQ: ").append(this.getPrimeExponentQ().toString(16)).append(nl); 238 buf.append(" crtCoefficient: ").append(this.getCrtCoefficient().toString(16)).append(nl); 239 240 return buf.toString(); 241 } 242 } 243