use of com.mindbright.security.pkcs1.RSAPublicKey in project SpringRemote by HaleyWang.
the class X509Certificate method getPublicKey.
public PublicKey getPublicKey() {
SubjectPublicKeyInfo spki = certificate.tbsCertificate.subjectPublicKeyInfo;
String alg = spki.algorithm.algorithmName().toUpperCase();
ASN1DER der = new ASN1DER();
if (alg.startsWith("RSA")) {
RSAPublicKey rsa = new RSAPublicKey();
ByteArrayInputStream ba = new ByteArrayInputStream(spki.subjectPublicKey.getBitArray());
try {
der.decode(ba, rsa);
} catch (Exception e) {
throw new Error("Internal error decoding SubjectPublicKeyInfo.subjectPublicKey: " + e.getMessage());
}
try {
KeyFactory keyFact = KeyFactory.getInstance("RSA");
RSAPublicKeySpec pubSpec = new RSAPublicKeySpec(rsa.modulus.getValue(), rsa.publicExponent.getValue());
return keyFact.generatePublic(pubSpec);
} catch (Exception e) {
throw new Error("Error creating RSA key: " + e.getMessage());
}
} else if (alg.startsWith("DSA")) {
DSAPublicKey dsa = new DSAPublicKey();
ByteArrayInputStream ba = new ByteArrayInputStream(spki.subjectPublicKey.getBitArray());
try {
der.decode(ba, dsa);
} catch (Exception e) {
throw new Error("Internal error decoding SubjectPublicKeyInfo.subjectPublicKey: " + e.getMessage());
}
BigInteger y = dsa.getValue();
DSAParams dsaParams = (DSAParams) spki.algorithm.parameters.getValue();
BigInteger p = dsaParams.p.getValue();
BigInteger q = dsaParams.q.getValue();
BigInteger g = dsaParams.g.getValue();
try {
KeyFactory dsaKeyFact = KeyFactory.getInstance("DSA");
DSAPublicKeySpec dsaPubSpec = new DSAPublicKeySpec(y, p, q, g);
return dsaKeyFact.generatePublic(dsaPubSpec);
} catch (Exception e) {
throw new Error("Error creating DSA key: " + e.getMessage());
}
} else {
throw new Error("Internal error decoding publicKey: unknown algorithm");
}
}
use of com.mindbright.security.pkcs1.RSAPublicKey in project apksig by venshine.
the class ApkSigningBlockUtils method encodePublicKey.
public static byte[] encodePublicKey(PublicKey publicKey) throws InvalidKeyException, NoSuchAlgorithmException {
byte[] encodedPublicKey = null;
if ("X.509".equals(publicKey.getFormat())) {
encodedPublicKey = publicKey.getEncoded();
// if the key is an RSA key check for a negative modulus
String keyAlgorithm = publicKey.getAlgorithm();
if ("RSA".equals(keyAlgorithm) || OID_RSA_ENCRYPTION.equals(keyAlgorithm)) {
try {
// Parse the encoded public key into the separate elements of the
// SubjectPublicKeyInfo to obtain the SubjectPublicKey.
ByteBuffer encodedPublicKeyBuffer = ByteBuffer.wrap(encodedPublicKey);
SubjectPublicKeyInfo subjectPublicKeyInfo = Asn1BerParser.parse(encodedPublicKeyBuffer, SubjectPublicKeyInfo.class);
// The SubjectPublicKey is encoded as a bit string within the
// SubjectPublicKeyInfo. The first byte of the encoding is the number of padding
// bits; store this and decode the rest of the bit string into the RSA modulus
// and exponent.
ByteBuffer subjectPublicKeyBuffer = subjectPublicKeyInfo.subjectPublicKey;
byte padding = subjectPublicKeyBuffer.get();
RSAPublicKey rsaPublicKey = Asn1BerParser.parse(subjectPublicKeyBuffer, RSAPublicKey.class);
// byte.
if (rsaPublicKey.modulus.compareTo(BigInteger.ZERO) < 0) {
// A negative modulus indicates the leading bit in the integer is 1. Per
// ASN.1 encoding rules to encode a positive integer with the leading bit
// set to 1 a byte containing all zeros should precede the integer encoding.
byte[] encodedModulus = rsaPublicKey.modulus.toByteArray();
byte[] reencodedModulus = new byte[encodedModulus.length + 1];
reencodedModulus[0] = 0;
System.arraycopy(encodedModulus, 0, reencodedModulus, 1, encodedModulus.length);
rsaPublicKey.modulus = new BigInteger(reencodedModulus);
// Once the modulus has been corrected reencode the RSAPublicKey, then
// restore the padding value in the bit string and reencode the entire
// SubjectPublicKeyInfo to be returned to the caller.
byte[] reencodedRSAPublicKey = Asn1DerEncoder.encode(rsaPublicKey);
byte[] reencodedSubjectPublicKey = new byte[reencodedRSAPublicKey.length + 1];
reencodedSubjectPublicKey[0] = padding;
System.arraycopy(reencodedRSAPublicKey, 0, reencodedSubjectPublicKey, 1, reencodedRSAPublicKey.length);
subjectPublicKeyInfo.subjectPublicKey = ByteBuffer.wrap(reencodedSubjectPublicKey);
encodedPublicKey = Asn1DerEncoder.encode(subjectPublicKeyInfo);
}
} catch (Asn1DecodingException | Asn1EncodingException e) {
System.out.println("Caught a exception encoding the public key: " + e);
e.printStackTrace();
encodedPublicKey = null;
}
}
}
if (encodedPublicKey == null) {
try {
encodedPublicKey = KeyFactory.getInstance(publicKey.getAlgorithm()).getKeySpec(publicKey, X509EncodedKeySpec.class).getEncoded();
} catch (InvalidKeySpecException e) {
throw new InvalidKeyException("Failed to obtain X.509 encoded form of public key " + publicKey + " of class " + publicKey.getClass().getName(), e);
}
}
if ((encodedPublicKey == null) || (encodedPublicKey.length == 0)) {
throw new InvalidKeyException("Failed to obtain X.509 encoded form of public key " + publicKey + " of class " + publicKey.getClass().getName());
}
return encodedPublicKey;
}
use of com.mindbright.security.pkcs1.RSAPublicKey in project apksig by venshine.
the class ApkSignerTest method testPublicKeyHasPositiveModulusAfterSigning.
@Test
public void testPublicKeyHasPositiveModulusAfterSigning() throws Exception {
// The V2 and V3 signature schemes include the public key from the certificate in the
// signing block. If a certificate with an RSAPublicKey is improperly encoded with a
// negative modulus this was previously written to the signing block as is and failed on
// device verification since on device the public key in the certificate was reencoded with
// the correct encoding for the modulus. This test uses an improperly encoded certificate to
// sign an APK and verifies that the public key in the signing block is corrected with a
// positive modulus to allow on device installs / updates.
List<ApkSigner.SignerConfig> signersList = Collections.singletonList(getDefaultSignerConfigFromResources(FIRST_RSA_2048_SIGNER_RESOURCE_NAME, FIRST_RSA_2048_SIGNER_CERT_WITH_NEGATIVE_MODULUS));
File signedApk = sign("original.apk", new ApkSigner.Builder(signersList).setV1SigningEnabled(true).setV2SigningEnabled(true).setV3SigningEnabled(true));
RSAPublicKey v2PublicKey = getRSAPublicKeyFromSigningBlock(signedApk, ApkSigningBlockUtils.VERSION_APK_SIGNATURE_SCHEME_V2);
assertTrue("The modulus in the public key in the V2 signing block must not be negative", v2PublicKey.modulus.compareTo(BigInteger.ZERO) > 0);
RSAPublicKey v3PublicKey = getRSAPublicKeyFromSigningBlock(signedApk, ApkSigningBlockUtils.VERSION_APK_SIGNATURE_SCHEME_V3);
assertTrue("The modulus in the public key in the V3 signing block must not be negative", v3PublicKey.modulus.compareTo(BigInteger.ZERO) > 0);
}
Aggregations