1 package org.bouncycastle.jce.provider; 2 3 import java.io.IOException; 4 import java.math.BigInteger; 5 import java.security.interfaces.RSAPublicKey; 6 import java.security.spec.RSAPublicKeySpec; 7 8 import org.bouncycastle.asn1.ASN1Sequence; 9 import org.bouncycastle.asn1.DERNull; 10 import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; 11 import org.bouncycastle.asn1.x509.AlgorithmIdentifier; 12 import org.bouncycastle.asn1.x509.RSAPublicKeyStructure; 13 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; 14 import org.bouncycastle.crypto.params.RSAKeyParameters; 15 import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; 16 17 public class JCERSAPublicKey 18 implements RSAPublicKey 19 { 20 static final long serialVersionUID = 2675817738516720772L; 21 22 private BigInteger modulus; 23 private BigInteger publicExponent; 24 25 JCERSAPublicKey( 26 RSAKeyParameters key) 27 { 28 this.modulus = key.getModulus(); 29 this.publicExponent = key.getExponent(); 30 } 31 32 JCERSAPublicKey( 33 RSAPublicKeySpec spec) 34 { 35 this.modulus = spec.getModulus(); 36 this.publicExponent = spec.getPublicExponent(); 37 } 38 39 JCERSAPublicKey( 40 RSAPublicKey key) 41 { 42 this.modulus = key.getModulus(); 43 this.publicExponent = key.getPublicExponent(); 44 } 45 46 JCERSAPublicKey( 47 SubjectPublicKeyInfo info) 48 { 49 try 50 { 51 RSAPublicKeyStructure pubKey = new RSAPublicKeyStructure((ASN1Sequence)info.parsePublicKey()); 52 53 this.modulus = pubKey.getModulus(); 54 this.publicExponent = pubKey.getPublicExponent(); 55 } 56 catch (IOException e) 57 { 58 throw new IllegalArgumentException("invalid info structure in RSA public key"); 59 } 60 } 61 62 /** 63 * return the modulus. 64 * 65 * @return the modulus. 66 */ 67 public BigInteger getModulus() 68 { 69 return modulus; 70 } 71 72 /** 73 * return the public exponent. 74 * 75 * @return the public exponent. 76 */ 77 public BigInteger getPublicExponent() 78 { 79 return publicExponent; 80 } 81 82 public String getAlgorithm() 83 { 84 return "RSA"; 85 } 86 87 public String getFormat() 88 { 89 return "X.509"; 90 } 91 92 public byte[] getEncoded() 93 { 94 // BEGIN android-changed 95 return KeyUtil.getEncodedSubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPublicKeyStructure(getModulus(), getPublicExponent())); 96 // END android-changed 97 } 98 99 public int hashCode() 100 { 101 return this.getModulus().hashCode() ^ this.getPublicExponent().hashCode(); 102 } 103 104 public boolean equals(Object o) 105 { 106 if (o == this) 107 { 108 return true; 109 } 110 111 if (!(o instanceof RSAPublicKey)) 112 { 113 return false; 114 } 115 116 RSAPublicKey key = (RSAPublicKey)o; 117 118 return getModulus().equals(key.getModulus()) 119 && getPublicExponent().equals(key.getPublicExponent()); 120 } 121 122 public String toString() 123 { 124 StringBuffer buf = new StringBuffer(); 125 String nl = System.getProperty("line.separator"); 126 127 buf.append("RSA Public Key").append(nl); 128 buf.append(" modulus: ").append(this.getModulus().toString(16)).append(nl); 129 buf.append(" public exponent: ").append(this.getPublicExponent().toString(16)).append(nl); 130 131 return buf.toString(); 132 } 133 } 134