private void validateKeys(PublicKey pubKey, PrivateKey privKey) { if (pubKey.getAlgorithm() != privKey.getAlgorithm()) throw new IllegalArgumentException("Public and private key have different algorithms"); // No encryption for DSA if (pubKey.getAlgorithm() != "RSA") return; try { String data = "ENCRYPT_DATA"; SecureRandom random = new SecureRandom(); Cipher cipher = Cipher.getInstance(pubKey.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privKey, random); byte[] encryptedData = cipher.doFinal(data.getBytes()); cipher.init(Cipher.DECRYPT_MODE, pubKey, random); String decreptedData = new String(cipher.doFinal(encryptedData)); if (!decreptedData.equals(data)) throw new IllegalArgumentException("Bad public-private key"); } catch (BadPaddingException e) { throw new IllegalArgumentException("Bad public-private key", e); } catch (IllegalBlockSizeException e) { throw new IllegalArgumentException("Bad public-private key", e); } catch (NoSuchPaddingException e) { throw new IllegalArgumentException("Bad public-private key", e); } catch (InvalidKeyException e) { throw new IllegalArgumentException("Invalid public-private key", e); } catch (NoSuchAlgorithmException e) { throw new IllegalArgumentException("Invalid algorithm for public-private key", e); } }
/** * Creates a test signature and verifies it. * * @param privateKey Private key to sign with * @param publicKey Public key to verify with * @param signatureProvider Name of provider to sign with * @throws NoSuchAlgorithmException In case the key or signature algorithm is unknown * @throws NoSuchProviderException In case the supplied provider name is unknown or BC is not * installed * @throws InvalidKeyException If signature verification failed or the key was invalid * @throws SignatureException If the signature could not be made or verified correctly */ public static void testSignAndVerify( PrivateKey privateKey, PublicKey publicKey, String signatureProvider) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, SignatureException { final byte input[] = "Lillan gick pa vagen ut, motte dar en katt...".getBytes(); final String sigAlg = suggestSigAlg(publicKey); if (sigAlg == null) { throw new NoSuchAlgorithmException("Unknown key algorithm: " + publicKey.getAlgorithm()); } if (LOG.isDebugEnabled()) { LOG.debug("Testing keys with algorithm: " + publicKey.getAlgorithm()); LOG.debug("testSigAlg: " + sigAlg); LOG.debug("provider: " + signatureProvider); LOG.trace("privateKey: " + privateKey); LOG.trace("privateKey class: " + privateKey.getClass().getName()); LOG.trace("publicKey: " + publicKey); LOG.trace("publicKey class: " + publicKey.getClass().getName()); } final Signature signSignature = Signature.getInstance(sigAlg, signatureProvider); signSignature.initSign(privateKey); signSignature.update(input); byte[] signBA = signSignature.sign(); if (LOG.isTraceEnabled()) { LOG.trace("Created signature of size: " + signBA.length); LOG.trace("Created signature: " + new String(Hex.encode(signBA))); } final Signature verifySignature = Signature.getInstance(sigAlg, "BC"); verifySignature.initVerify(publicKey); verifySignature.update(input); if (!verifySignature.verify(signBA)) { throw new InvalidKeyException("Test signature inconsistent"); } }
public KeySelectorResult select( KeyInfo keyInfo, KeySelector.Purpose purpose, AlgorithmMethod method, XMLCryptoContext context) throws KeySelectorException { if (keyInfo == null) { throw new KeySelectorException("Null KeyInfo object!"); } SignatureMethod sm = (SignatureMethod) method; List list = keyInfo.getContent(); for (int i = 0; i < list.size(); i++) { XMLStructure xmlStructure = (XMLStructure) list.get(i); if (xmlStructure instanceof KeyValue) { PublicKey pk = null; try { pk = ((KeyValue) xmlStructure).getPublicKey(); } catch (KeyException ke) { throw new KeySelectorException(ke); } // make sure algorithm is compatible with method if (algEquals(sm.getAlgorithm(), pk.getAlgorithm())) { curPK = pk; // System.out.println("Public Key is SOAP: " + getHexString(pk.getEncoded())); // System.out.println("Public Key is SOAP: " +getHexString(LoadPublicKey("", // "RSA").getEncoded())); return new SimpleKeySelectorResult(pk); } } } throw new KeySelectorException("No KeyValue element found!"); }
/** * Checks whether the supplied public key matches one of the supplied {@link DEREncodedKeyValue} * elements. * * <p>Matches are performed using Java <code>equals()</code> against {@link PublicKey}s decoded * from the KeyInfo data. * * @param key public key presenter of the assertion * @param derEncodedKeyValues candidate DEREncodedKeyValue elements * @return true if the public key in the certificate matches one of the DER-encoded key values, * false otherwise * @throws AssertionValidationException thrown if there is a problem matching the key value */ protected boolean matchesDEREncodedKeyValue( @Nonnull final PublicKey key, @Nullable final List<DEREncodedKeyValue> derEncodedKeyValues) { if (derEncodedKeyValues == null || derEncodedKeyValues.isEmpty()) { log.debug("KeyInfo contained no DEREncodedKeyValue children"); return false; } log.debug( "Attempting to match KeyInfo DEREncodedKeyValue to supplied PublicKey param of type: {}", key.getAlgorithm()); for (DEREncodedKeyValue derEncodedKeyValue : derEncodedKeyValues) { try { PublicKey kiPublicKey = KeyInfoSupport.getKey(derEncodedKeyValue); if (Objects.equals(key, kiPublicKey)) { log.debug("Matched DEREncodedKeyValue PublicKey"); return true; } } catch (KeyException e) { log.warn("KeyInfo contained DEREncodedKeyValue that can not be parsed", e); } } log.debug("Failed to match any DEREncodedKeyValue"); return false; }
/** * Convert a public key to the SSH format. * * <p>Note that only RSA keys are supported at the moment. * * @param key the public key to convert * @return an array of bytes that can with the representation of the public key */ public static byte[] getKeyBytes(final PublicKey key) { // We only support RSA at the moment: if (!(key instanceof RSAPublicKey)) { log.error( "The key algorithm \"" + key.getAlgorithm() + "\" is not supported, will return null."); return null; } // Extract the bytes of the exponent and the modulus // of the key: final RSAPublicKey rsaKey = (RSAPublicKey) key; final byte[] exponentBytes = rsaKey.getPublicExponent().toByteArray(); final byte[] modulusBytes = rsaKey.getModulus().toByteArray(); if (log.isDebugEnabled()) { log.debug( "Exponent is " + rsaKey.getPublicExponent() + " (" + Hex.encodeHexString(exponentBytes) + ")."); log.debug( "Modulus is " + rsaKey.getModulus() + " (" + Hex.encodeHexString(exponentBytes) + ")."); } try { // Prepare the stream to write the binary SSH key: final ByteArrayOutputStream binaryOut = new ByteArrayOutputStream(); final DataOutputStream dataOut = new DataOutputStream(binaryOut); // Write the SSH header (4 bytes for the length of the algorithm // name and then the algorithm name): dataOut.writeInt(SSH_RSA.length()); dataOut.writeBytes(SSH_RSA); // Write the exponent and modulus bytes (note that it is not // necessary to check if the most significative bit is one, as // that will never happen with byte arrays created from big // integers, unless they are negative, which is not the case // for RSA modulus or exponents): dataOut.writeInt(exponentBytes.length); dataOut.write(exponentBytes); dataOut.writeInt(modulusBytes.length); dataOut.write(modulusBytes); // Done, extract the bytes: binaryOut.close(); final byte[] keyBytes = binaryOut.toByteArray(); if (log.isDebugEnabled()) { log.debug("Key bytes are " + Hex.encodeHexString(keyBytes) + "."); } return keyBytes; } catch (IOException exception) { log.error("Error while serializing public key, will return null.", exception); return null; } }
private static JcaContentSignerBuilder makeContentSignerBuilder(PublicKey issPub) { JcaContentSignerBuilder contentSignerBuilder; if (issPub instanceof RSAPublicKey) { contentSignerBuilder = new JcaContentSignerBuilder("SHA1WithRSA"); } else if (issPub.getAlgorithm().equals("DSA")) { contentSignerBuilder = new JcaContentSignerBuilder("SHA1withDSA"); } else if (issPub.getAlgorithm().equals("ECDSA")) { contentSignerBuilder = new JcaContentSignerBuilder("SHA1withECDSA"); } else if (issPub.getAlgorithm().equals("ECGOST3410")) { contentSignerBuilder = new JcaContentSignerBuilder("GOST3411withECGOST3410"); } else { contentSignerBuilder = new JcaContentSignerBuilder("GOST3411WithGOST3410"); } contentSignerBuilder.setProvider(BouncyCastleProvider.PROVIDER_NAME); return contentSignerBuilder; }
/** * Generate a certificate signing request (PKCS#10). * * @param info A PKCS10CertReqInfo * @param privateKey Private key for signing the request * @param signatureProvider Name of provider to sign with * @param publicKey Public key to include in the request * @param explicitEccParameters True if the EC domain parameters should be included (ie. not a * named curve) * @return the certificate request data */ public static ICertReqData genCertificateRequest( ISignerCertReqInfo info, final PrivateKey privateKey, final String signatureProvider, PublicKey publicKey, final boolean explicitEccParameters) throws IllegalArgumentException { LOG.debug(">genCertificateRequest"); final Base64SignerCertReqData retval; if (info instanceof PKCS10CertReqInfo) { PKCS10CertReqInfo reqInfo = (PKCS10CertReqInfo) info; PKCS10CertificationRequest pkcs10; if (LOG.isDebugEnabled()) { LOG.debug("signatureAlgorithm: " + reqInfo.getSignatureAlgorithm()); LOG.debug("subjectDN: " + reqInfo.getSubjectDN()); LOG.debug("explicitEccParameters: " + explicitEccParameters); } try { // Handle ECDSA key with explicit parameters if (explicitEccParameters && publicKey.getAlgorithm().contains("EC")) { publicKey = ECKeyUtil.publicToExplicitParameters(publicKey, "BC"); } if (LOG.isDebugEnabled()) { LOG.debug("Public key SHA1: " + createKeyHash(publicKey)); LOG.debug("Public key SHA256: " + KeyUsageCounterHash.create(publicKey)); } // Generate request final JcaPKCS10CertificationRequestBuilder builder = new JcaPKCS10CertificationRequestBuilder( new X500Name(CertTools.stringToBCDNString(reqInfo.getSubjectDN())), publicKey); final ContentSigner contentSigner = new JcaContentSignerBuilder(reqInfo.getSignatureAlgorithm()) .setProvider(signatureProvider) .build(privateKey); pkcs10 = builder.build(contentSigner); retval = new Base64SignerCertReqData(Base64.encode(pkcs10.getEncoded())); } catch (IOException e) { throw new IllegalArgumentException("Certificate request error: " + e.getMessage(), e); } catch (OperatorCreationException e) { throw new IllegalArgumentException("Certificate request error: " + e.getMessage(), e); } catch (NoSuchAlgorithmException e) { throw new IllegalArgumentException("Certificate request error: " + e.getMessage(), e); } catch (NoSuchProviderException e) { throw new IllegalArgumentException("Certificate request error: " + e.getMessage(), e); } LOG.debug("<genCertificateRequest"); return retval; } else { throw new IllegalArgumentException( "Unsupported certificate request info type: " + info.getClass().getName()); } }
/** * Creates a new content verifier using default algorithm. * * @param key the private key * @return a new content verifier * @throws OperatorCreationException if the content signer cannot be created */ public static ContentVerifierProvider createDefaultContentVerifier(PublicKey key) throws OperatorCreationException { if ("RSA" == key.getAlgorithm()) { // SunRsaSign supports only RSA signatures but it is (for some reason) about 2x faster // than the BC implementation return SUN_VERIFICATION_BUILDER.build(key); } else { return BC_VERIFICATION_BUILDER.build(key); } }
public KeyValue newKeyValue(PublicKey key) throws KeyException { String algorithm = key.getAlgorithm(); if (algorithm.equals("DSA")) { return new DOMKeyValue.DSA(key); } else if (algorithm.equals("RSA")) { return new DOMKeyValue.RSA(key); } else if (algorithm.equals("EC")) { return new DOMKeyValue.EC(key); } else { throw new KeyException("unsupported key algorithm: " + algorithm); } }
/** * Creates new encrypted credentials * * <p>Encrypts the message '<code>login</code>:<code>password</code>' using the public key <code> * pubKey</code> and <code>cipher</code> and store it in a new Credentials object. * * @see KeyPairUtil#encrypt(String, String, String, byte[]) * @param login the login to encrypt * @param password the corresponding password to encrypt * @param pubKey public key used for encryption * @param cipher cipher parameters: combination of transformations * @return the Credentials object containing the encrypted data * @throws KeyException key generation or encryption failed */ @Deprecated public static Credentials createCredentials( String login, String password, byte[] datakey, PublicKey pubKey, String cipher) throws KeyException { CredData cc = new CredData(); cc.setLogin(CredData.parseLogin(login)); cc.setDomain(CredData.parseDomain(login)); cc.setPassword(password); cc.setKey(datakey); // serialize clear credentials to byte array byte[] clearCred = null; try { clearCred = ObjectToByteConverter.ObjectStream.convert(cc); } catch (IOException e1) { throw new KeyException(e1.getMessage()); } int size = -1; if (pubKey instanceof java.security.interfaces.RSAPublicKey) { size = ((RSAPublicKey) pubKey).getModulus().bitLength(); } else if (pubKey instanceof java.security.interfaces.DSAPublicKey) { size = ((DSAPublicKey) pubKey).getParams().getP().bitLength(); } else if (pubKey instanceof javax.crypto.interfaces.DHPublicKey) { size = ((DHPublicKey) pubKey).getParams().getP().bitLength(); } // generate symmetric key SecretKey aesKey = KeyUtil.generateKey(AES_ALGO, AES_KEYSIZE); byte[] encData = null; byte[] encAes = null; // encrypt AES key with public RSA key try { encAes = KeyPairUtil.encrypt(pubKey, size, cipher, aesKey.getEncoded()); } catch (KeyException e) { throw new KeyException("Symmetric key encryption failed", e); } // encrypt clear credentials with AES key try { encData = KeyUtil.encrypt(aesKey, AES_CIPHER, clearCred); } catch (KeyException e) { throw new KeyException("Message encryption failed", e); } Credentials cred = new Credentials(pubKey.getAlgorithm(), size, cipher, encAes, encData); return cred; }
public void putRawPublicKey(PublicKey key) { if (key instanceof RSAPublicKey) { putString(KeyPairProvider.SSH_RSA); putMPInt(((RSAPublicKey) key).getPublicExponent()); putMPInt(((RSAPublicKey) key).getModulus()); } else if (key instanceof DSAPublicKey) { putString(KeyPairProvider.SSH_DSS); putMPInt(((DSAPublicKey) key).getParams().getP()); putMPInt(((DSAPublicKey) key).getParams().getQ()); putMPInt(((DSAPublicKey) key).getParams().getG()); putMPInt(((DSAPublicKey) key).getY()); } else { throw new IllegalStateException("Unsupported algorithm: " + key.getAlgorithm()); } }
private void parseCertificate() throws CertificateException, KeyczarException { Certificate certificate = CertificateFactory.getInstance("X.509").generateCertificate(certificateStream); PublicKey publicKey = certificate.getPublicKey(); if (publicKey instanceof RSAPublicKey) { key = readRsaX509Certificate(publicKey, padding); } else if (publicKey instanceof DSAPublicKey) { if (padding != null) { throw new KeyczarException(Messages.getString("InvalidPadding", padding.name())); } key = readDsaX509Certificate(publicKey); } else { throw new KeyczarException( "Unrecognized key type " + publicKey.getAlgorithm() + " in certificate"); } }
/** * Verify the signature value computed over the supplied input against the supplied signature * value. * * <p>It is up to the caller to ensure that the specified algorithm ID is consistent with the type * of verification key supplied. * * @param verificationKey the key with which to compute and verify the signature * @param jcaAlgorithmID the Java JCA algorithm ID to use * @param signature the computed signature value received from the signer * @param input the input over which the signature is computed and verified * @return true if the signature value computed over the input using the supplied key and * algorithm ID is identical to the supplied signature value * @throws SecurityException thrown if the signature computation or verification process results * in an error */ public static boolean verify( PublicKey verificationKey, String jcaAlgorithmID, byte[] signature, byte[] input) throws SecurityException { log.debug( "Verifying signature over input using public key of type {} and JCA algorithm ID {}", verificationKey.getAlgorithm(), jcaAlgorithmID); try { Signature sig = Signature.getInstance(jcaAlgorithmID); sig.initVerify(verificationKey); sig.update(input); return sig.verify(signature); } catch (GeneralSecurityException e) { log.error("Error during signature verification", e); throw new SecurityException("Error during signature verification", e); } }
public String toString() { StringWriter str = new StringWriter(); PrintWriter out = new PrintWriter(str); out.println(X509CertificateImpl.class.getName() + " {"); out.println(" TBSCertificate {"); out.println(" version = " + version + ";"); out.println(" serialNo = " + serialNo + ";"); out.println(" signature = {"); out.println(" algorithm = " + getSigAlgName() + ";"); out.print(" parameters ="); if (sigAlgVal != null) { out.println(); out.print(Util.hexDump(sigAlgVal, " ")); } else { out.println(" null;"); } out.println(" }"); out.println(" issuer = " + issuer.getName() + ";"); out.println(" validity = {"); out.println(" notBefore = " + notBefore + ";"); out.println(" notAfter = " + notAfter + ";"); out.println(" }"); out.println(" subject = " + subject.getName() + ";"); out.println(" subjectPublicKeyInfo = {"); out.println(" algorithm = " + subjectKey.getAlgorithm()); out.println(" key ="); out.print(Util.hexDump(subjectKey.getEncoded(), " ")); out.println(" };"); out.println(" issuerUniqueId = " + issuerUniqueId + ";"); out.println(" subjectUniqueId = " + subjectUniqueId + ";"); out.println(" extensions = {"); for (Iterator it = extensions.values().iterator(); it.hasNext(); ) { out.println(" " + it.next()); } out.println(" }"); out.println(" }"); out.println(" signatureAlgorithm = " + getSigAlgName() + ";"); out.println(" signatureValue ="); out.print(Util.hexDump(signature, " ")); out.println("}"); return str.toString(); }
@Override public KeySelectorResult select( final KeyInfo ki, final Purpose p, final AlgorithmMethod m, final XMLCryptoContext c) throws KeySelectorException { if (ki == null) throw new KeySelectorException("KeyInfo is null"); final SignatureMethod sm = (SignatureMethod) m; @SuppressWarnings("unchecked") final List<Object> list = ki.getContent(); for (final Object l : list) { final XMLStructure s = (XMLStructure) l; PublicKey pk = null; if (s instanceof KeyValue) { try { pk = ((KeyValue) s).getPublicKey(); } catch (final KeyException ke) { throw new KeySelectorException(ke); } } else if (s instanceof X509Data) { for (final Object d : ((X509Data) s).getContent()) { if (d instanceof X509Certificate) { pk = ((Certificate) d).getPublicKey(); } } } if (pk != null) { final String sa = sm.getAlgorithm(); final String ka = pk.getAlgorithm(); if ("DSA".equalsIgnoreCase(ka) && "http://www.w3.org/2000/09/xmldsig#dsa-sha1".equals(sa) || "RSA".equalsIgnoreCase(ka) && "http://www.w3.org/2000/09/xmldsig#rsa-sha1".equals(sa)) { return new MyKeySelectorResult(pk); } } } throw new KeySelectorException("No KeyValue element found"); }
/** * Encodes a public key data the same way as the {@link #parsePublicKeyEntry(String)} expects it * * @param <A> The generic appendable class * @param sb The {@link Appendable} instance to encode the data into * @param key The {@link PublicKey} - ignored if {@code null} * @return The updated appendable instance * @throws IOException If failed to append the data */ public static <A extends Appendable> A appendPublicKeyEntry(A sb, PublicKey key) throws IOException { if (key == null) { return sb; } @SuppressWarnings("unchecked") PublicKeyEntryDecoder<PublicKey, ?> decoder = (PublicKeyEntryDecoder<PublicKey, ?>) KeyUtils.getPublicKeyEntryDecoder(key); if (decoder == null) { throw new StreamCorruptedException("Cannot retrieve decoder for key=" + key.getAlgorithm()); } try (ByteArrayOutputStream s = new ByteArrayOutputStream(Byte.MAX_VALUE)) { String keyType = decoder.encodePublicKey(s, key); byte[] bytes = s.toByteArray(); String b64Data = Base64.encodeToString(bytes); sb.append(keyType).append(' ').append(b64Data); } return sb; }
@JRubyMethod(name = "read", meta = true, required = 1, optional = 1) public static IRubyObject read( final ThreadContext context, IRubyObject recv, IRubyObject[] args) { final Ruby runtime = context.runtime; final IRubyObject data; final char[] pass; switch (args.length) { case 1: data = args[0]; pass = null; break; default: data = args[0]; pass = args[1].isNil() ? null : args[1].toString().toCharArray(); } final byte[] input = OpenSSLImpl.readX509PEM(context, data); KeyPair key = null; // d2i_PrivateKey_bio try { key = readPrivateKey(input); } catch (IOException ioe) { // ignore } catch (GeneralSecurityException gse) { // ignore } // PEM_read_bio_PrivateKey if (key == null) { try { key = PEMInputOutput.readPrivateKey( new InputStreamReader(new ByteArrayInputStream(input)), pass); } catch (IOException ioe) { // ignore } } if (key != null) { if (key.getPublic().getAlgorithm().equals("RSA")) { return new PKeyRSA( runtime, _PKey(runtime).getClass("RSA"), (RSAPrivateCrtKey) key.getPrivate(), (RSAPublicKey) key.getPublic()); } else if (key.getPublic().getAlgorithm().equals("DSA")) { return new PKeyDSA( runtime, _PKey(runtime).getClass("DSA"), (DSAPrivateKey) key.getPrivate(), (DSAPublicKey) key.getPublic()); } } PublicKey pubKey = null; // d2i_PUBKEY_bio try { pubKey = readPublicKey(input); } catch (IOException ioe) { // ignore } catch (GeneralSecurityException gse) { // ignore } // PEM_read_bio_PUBKEY if (pubKey == null) { try { pubKey = PEMInputOutput.readPubKey(new InputStreamReader(new ByteArrayInputStream(input))); } catch (IOException ioe) { // ignore } } if (pubKey != null) { if (pubKey.getAlgorithm().equals("RSA")) { return new PKeyRSA(runtime, _PKey(runtime).getClass("RSA"), (RSAPublicKey) pubKey); } else if (key.getPublic().getAlgorithm().equals("DSA")) { return new PKeyDSA(runtime, _PKey(runtime).getClass("DSA"), (DSAPublicKey) pubKey); } } throw runtime.newArgumentError("Could not parse PKey"); }