protected <T extends KeySpec> T engineGetKeySpec(Key key, Class<T> keySpec) throws InvalidKeySpecException { try { // convert key to one of our keys // this also verifies that the key is a valid RSA key and ensures // that the encoding is X.509/PKCS#8 for public/private keys key = engineTranslateKey(key); } catch (InvalidKeyException e) { throw new InvalidKeySpecException(e); } if (key instanceof RSAPublicKey) { RSAPublicKey rsaKey = (RSAPublicKey) key; if (rsaPublicKeySpecClass.isAssignableFrom(keySpec)) { return keySpec.cast(new RSAPublicKeySpec(rsaKey.getModulus(), rsaKey.getPublicExponent())); } else if (x509KeySpecClass.isAssignableFrom(keySpec)) { return keySpec.cast(new X509EncodedKeySpec(key.getEncoded())); } else { throw new InvalidKeySpecException( "KeySpec must be RSAPublicKeySpec or " + "X509EncodedKeySpec for RSA public keys"); } } else if (key instanceof RSAPrivateKey) { if (pkcs8KeySpecClass.isAssignableFrom(keySpec)) { return keySpec.cast(new PKCS8EncodedKeySpec(key.getEncoded())); } else if (rsaPrivateCrtKeySpecClass.isAssignableFrom(keySpec)) { if (key instanceof RSAPrivateCrtKey) { RSAPrivateCrtKey crtKey = (RSAPrivateCrtKey) key; return keySpec.cast( new RSAPrivateCrtKeySpec( crtKey.getModulus(), crtKey.getPublicExponent(), crtKey.getPrivateExponent(), crtKey.getPrimeP(), crtKey.getPrimeQ(), crtKey.getPrimeExponentP(), crtKey.getPrimeExponentQ(), crtKey.getCrtCoefficient())); } else { throw new InvalidKeySpecException("RSAPrivateCrtKeySpec can only be used with CRT keys"); } } else if (rsaPrivateKeySpecClass.isAssignableFrom(keySpec)) { RSAPrivateKey rsaKey = (RSAPrivateKey) key; return keySpec.cast( new RSAPrivateKeySpec(rsaKey.getModulus(), rsaKey.getPrivateExponent())); } else { throw new InvalidKeySpecException( "KeySpec must be RSAPrivate(Crt)KeySpec or " + "PKCS8EncodedKeySpec for RSA private keys"); } } else { // should not occur, caught in engineTranslateKey() throw new InvalidKeySpecException("Neither public nor private key"); } }
private static void test(PrivateKey privateKey, PublicKey publicKey) throws Exception { testSignature("MD2withRSA", privateKey, publicKey); testSignature("MD5withRSA", privateKey, publicKey); testSignature("SHA1withRSA", privateKey, publicKey); testSignature("SHA224withRSA", privateKey, publicKey); testSignature("SHA256withRSA", privateKey, publicKey); RSAPublicKey rsaKey = (RSAPublicKey) publicKey; if (rsaKey.getModulus().bitLength() > 512) { // for SHA384 and SHA512 the data is too long for 512 bit keys testSignature("SHA384withRSA", privateKey, publicKey); testSignature("SHA512withRSA", privateKey, publicKey); } }
static byte[] buildRSA(RSAPublicKey key) { DataByteOutputStream out = new DataByteOutputStream(); BigInteger exponent = key.getPublicExponent(); BigInteger modulus = key.getModulus(); int exponentLength = BigIntegerLength(exponent); if (exponentLength < 256) out.writeByte(exponentLength); else { out.writeByte(0); out.writeShort(exponentLength); } out.writeBigInteger(exponent); out.writeBigInteger(modulus); return out.toByteArray(); }
// internal implementation of translateKey() for public keys. See JCA doc private PublicKey translatePublicKey(PublicKey key) throws InvalidKeyException { if (key instanceof RSAPublicKey) { if (key instanceof RSAPublicKeyImpl) { return key; } RSAPublicKey rsaKey = (RSAPublicKey) key; try { return new RSAPublicKeyImpl(rsaKey.getModulus(), rsaKey.getPublicExponent()); } catch (RuntimeException e) { // catch providers that incorrectly implement RSAPublicKey throw new InvalidKeyException("Invalid key", e); } } else if ("X.509".equals(key.getFormat())) { byte[] encoded = key.getEncoded(); return new RSAPublicKeyImpl(encoded); } else { throw new InvalidKeyException( "Public keys must be instance " + "of RSAPublicKey or have X.509 encoding"); } }
/** * Appends an HTML representation of the given X509Certificate. * * @param sb StringBuilder to append to * @param certificate to print */ private void renderX509(StringBuilder sb, X509Certificate certificate) { X500Principal issuer = certificate.getIssuerX500Principal(); X500Principal subject = certificate.getSubjectX500Principal(); sb.append("<table cellspacing='1' cellpadding='1'>\n"); // subject addTitle(sb, R.getI18NString("service.gui.CERT_INFO_ISSUED_TO")); try { for (Rdn name : new LdapName(subject.getName()).getRdns()) { String nameType = name.getType(); String lblKey = "service.gui.CERT_INFO_" + nameType; String lbl = R.getI18NString(lblKey); if ((lbl == null) || ("!" + lblKey + "!").equals(lbl)) lbl = nameType; final String value; Object nameValue = name.getValue(); if (nameValue instanceof byte[]) { byte[] nameValueAsByteArray = (byte[]) nameValue; value = getHex(nameValueAsByteArray) + " (" + new String(nameValueAsByteArray) + ")"; } else value = nameValue.toString(); addField(sb, lbl, value); } } catch (InvalidNameException ine) { addField(sb, R.getI18NString("service.gui.CERT_INFO_CN"), subject.getName()); } // issuer addTitle(sb, R.getI18NString("service.gui.CERT_INFO_ISSUED_BY")); try { for (Rdn name : new LdapName(issuer.getName()).getRdns()) { String nameType = name.getType(); String lblKey = "service.gui.CERT_INFO_" + nameType; String lbl = R.getI18NString(lblKey); if ((lbl == null) || ("!" + lblKey + "!").equals(lbl)) lbl = nameType; final String value; Object nameValue = name.getValue(); if (nameValue instanceof byte[]) { byte[] nameValueAsByteArray = (byte[]) nameValue; value = getHex(nameValueAsByteArray) + " (" + new String(nameValueAsByteArray) + ")"; } else value = nameValue.toString(); addField(sb, lbl, value); } } catch (InvalidNameException ine) { addField(sb, R.getI18NString("service.gui.CERT_INFO_CN"), issuer.getName()); } // validity addTitle(sb, R.getI18NString("service.gui.CERT_INFO_VALIDITY")); addField( sb, R.getI18NString("service.gui.CERT_INFO_ISSUED_ON"), certificate.getNotBefore().toString()); addField( sb, R.getI18NString("service.gui.CERT_INFO_EXPIRES_ON"), certificate.getNotAfter().toString()); addTitle(sb, R.getI18NString("service.gui.CERT_INFO_FINGERPRINTS")); try { String sha1String = getThumbprint(certificate, "SHA1"); String md5String = getThumbprint(certificate, "MD5"); addField(sb, "SHA1:", sha1String); addField(sb, "MD5:", md5String); } catch (CertificateException e) { // do nothing as we cannot show this value } addTitle(sb, R.getI18NString("service.gui.CERT_INFO_CERT_DETAILS")); addField( sb, R.getI18NString("service.gui.CERT_INFO_SER_NUM"), certificate.getSerialNumber().toString()); addField( sb, R.getI18NString("service.gui.CERT_INFO_VER"), String.valueOf(certificate.getVersion())); addField( sb, R.getI18NString("service.gui.CERT_INFO_SIGN_ALG"), String.valueOf(certificate.getSigAlgName())); addTitle(sb, R.getI18NString("service.gui.CERT_INFO_PUB_KEY_INFO")); addField( sb, R.getI18NString("service.gui.CERT_INFO_ALG"), certificate.getPublicKey().getAlgorithm()); if (certificate.getPublicKey().getAlgorithm().equals("RSA")) { RSAPublicKey key = (RSAPublicKey) certificate.getPublicKey(); addField( sb, R.getI18NString("service.gui.CERT_INFO_PUB_KEY"), R.getI18NString( "service.gui.CERT_INFO_KEY_BYTES_PRINT", new String[] { String.valueOf(key.getModulus().toByteArray().length - 1), key.getModulus().toString(16) })); addField( sb, R.getI18NString("service.gui.CERT_INFO_EXP"), key.getPublicExponent().toString()); addField( sb, R.getI18NString("service.gui.CERT_INFO_KEY_SIZE"), R.getI18NString( "service.gui.CERT_INFO_KEY_BITS_PRINT", new String[] {String.valueOf(key.getModulus().bitLength())})); } else if (certificate.getPublicKey().getAlgorithm().equals("DSA")) { DSAPublicKey key = (DSAPublicKey) certificate.getPublicKey(); addField(sb, "Y:", key.getY().toString(16)); } addField( sb, R.getI18NString("service.gui.CERT_INFO_SIGN"), R.getI18NString( "service.gui.CERT_INFO_KEY_BYTES_PRINT", new String[] { String.valueOf(certificate.getSignature().length), getHex(certificate.getSignature()) })); sb.append("</table>\n"); }