private DERObject createDERForRecipient(byte[] in, X509Certificate cert) throws IOException, GeneralSecurityException { String s = "1.2.840.113549.3.2"; AlgorithmParameterGenerator algorithmparametergenerator = AlgorithmParameterGenerator.getInstance(s); AlgorithmParameters algorithmparameters = algorithmparametergenerator.generateParameters(); ByteArrayInputStream bytearrayinputstream = new ByteArrayInputStream(algorithmparameters.getEncoded("ASN.1")); ASN1InputStream asn1inputstream = new ASN1InputStream(bytearrayinputstream); DERObject derobject = asn1inputstream.readObject(); KeyGenerator keygenerator = KeyGenerator.getInstance(s); keygenerator.init(128); SecretKey secretkey = keygenerator.generateKey(); Cipher cipher = Cipher.getInstance(s); cipher.init(1, secretkey, algorithmparameters); byte[] abyte1 = cipher.doFinal(in); DEROctetString deroctetstring = new DEROctetString(abyte1); KeyTransRecipientInfo keytransrecipientinfo = computeRecipientInfo(cert, secretkey.getEncoded()); DERSet derset = new DERSet(new RecipientInfo(keytransrecipientinfo)); AlgorithmIdentifier algorithmidentifier = new AlgorithmIdentifier(new DERObjectIdentifier(s), derobject); EncryptedContentInfo encryptedcontentinfo = new EncryptedContentInfo(PKCSObjectIdentifiers.data, algorithmidentifier, deroctetstring); EnvelopedData env = new EnvelopedData(null, derset, encryptedcontentinfo, null); ContentInfo contentinfo = new ContentInfo(PKCSObjectIdentifiers.envelopedData, env); return contentinfo.getDERObject(); }
/** * @tests javax.crypto.Cipher#getParameters() * @tests javax.crypto.Cipher#init(int, java.security.Key, java.security.AlgorithmParameters, * java.security.SecureRandom) */ public void test_getParameters() throws Exception { /* * If this test is changed, implement the following: * test_initILjava_security_KeyLjava_security_AlgorithmParametersLjava_security_SecureRandom() */ SecureRandom sr = new SecureRandom(); Cipher cipher = null; byte[] apEncoding = null; byte[] iv = new byte[8]; sr.nextBytes(iv); AlgorithmParameters ap = AlgorithmParameters.getInstance("DESede"); ap.init(iv, "RAW"); apEncoding = ap.getEncoded("ASN.1"); cipher = Cipher.getInstance(algorithm + "/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, cipherKey, ap, sr); byte[] cipherParmsEnc = cipher.getParameters().getEncoded("ASN.1"); assertTrue("Parameters differ", Arrays.equals(apEncoding, cipherParmsEnc)); }
private void testParameters() throws Exception { AlgorithmParameterGenerator a = AlgorithmParameterGenerator.getInstance("DSA", "BC"); a.init(512, random); AlgorithmParameters params = a.generateParameters(); byte[] encodeParams = params.getEncoded(); AlgorithmParameters a2 = AlgorithmParameters.getInstance("DSA", "BC"); a2.init(encodeParams); // a and a2 should be equivalent! byte[] encodeParams_2 = a2.getEncoded(); if (!areEqual(encodeParams, encodeParams_2)) { fail("encode/decode parameters failed"); } DSAParameterSpec dsaP = (DSAParameterSpec) params.getParameterSpec(DSAParameterSpec.class); KeyPairGenerator g = KeyPairGenerator.getInstance("DSA", "BC"); g.initialize(dsaP, new SecureRandom()); KeyPair p = g.generateKeyPair(); PrivateKey sKey = p.getPrivate(); PublicKey vKey = p.getPublic(); Signature s = Signature.getInstance("DSA", "BC"); byte[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}; s.initSign(sKey); s.update(data); byte[] sigBytes = s.sign(); s = Signature.getInstance("DSA", "BC"); s.initVerify(vKey); s.update(data); if (!s.verify(sigBytes)) { fail("DSA verification failed"); } }
private void testRandom(int size) throws Exception { AlgorithmParameterGenerator a = AlgorithmParameterGenerator.getInstance("ElGamal", "BC"); a.init(size, new SecureRandom()); AlgorithmParameters params = a.generateParameters(); byte[] encodeParams = params.getEncoded(); AlgorithmParameters a2 = AlgorithmParameters.getInstance("ElGamal", "BC"); a2.init(encodeParams); // a and a2 should be equivalent! byte[] encodeParams_2 = a2.getEncoded(); if (!areEqual(encodeParams, encodeParams_2)) { fail(this.getName() + ": encode/decode parameters failed"); } DHParameterSpec elP = (DHParameterSpec) params.getParameterSpec(DHParameterSpec.class); testGP(size, 0, elP.getG(), elP.getP()); }
private void testGCMGeneric(byte[] K, byte[] N, byte[] A, byte[] P, byte[] C) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, NoSuchProviderException, IOException, InvalidParameterSpecException { Cipher eax = Cipher.getInstance("AES/GCM/NoPadding", "BC"); SecretKeySpec key = new SecretKeySpec(K, "AES"); // GCMParameterSpec mapped to AEADParameters and overrides default MAC // size GCMParameterSpec spec = new GCMParameterSpec(128, N); eax.init(Cipher.ENCRYPT_MODE, key, spec); eax.updateAAD(A); byte[] c = eax.doFinal(P); if (!areEqual(C, c)) { fail("JCE encrypt with additional data and GCMParameterSpec failed."); } eax = Cipher.getInstance("GCM", "BC"); eax.init(Cipher.DECRYPT_MODE, key, spec); eax.updateAAD(A); byte[] p = eax.doFinal(C); if (!areEqual(P, p)) { fail("JCE decrypt with additional data and GCMParameterSpec failed."); } AlgorithmParameters algParams = eax.getParameters(); byte[] encParams = algParams.getEncoded(); GCMParameters gcmParameters = GCMParameters.getInstance(encParams); if (!Arrays.areEqual(spec.getIV(), gcmParameters.getNonce()) || spec.getTLen() != gcmParameters.getIcvLen()) { fail("parameters mismatch"); } GCMParameterSpec gcmSpec = algParams.getParameterSpec(GCMParameterSpec.class); if (!Arrays.areEqual(gcmSpec.getIV(), gcmParameters.getNonce()) || gcmSpec.getTLen() != gcmParameters.getIcvLen() * 8) { fail("spec parameters mismatch"); } if (!Arrays.areEqual(eax.getIV(), gcmParameters.getNonce())) { fail("iv mismatch"); } }
private void encode() throws IOException { List algId = new ArrayList(2); algId.add(new DERValue(DER.OBJECT_IDENTIFIER, algOid)); getAlgParameters(); if (params != null) { algId.add(DERReader.read(params.getEncoded())); } else { algId.add(new DERValue(DER.NULL, null)); } List epki = new ArrayList(2); epki.add(new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, algId)); epki.add(new DERValue(DER.OCTET_STRING, encryptedData)); encoded = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, epki).getEncoded(); }
private static byte[] testParams(AlgorithmParameters rc2Params, RC2ParameterSpec rc2Spec) throws Exception { // test getParameterSpec returns object equal to input rc2Params.init(rc2Spec); RC2ParameterSpec rc2OtherSpec = (RC2ParameterSpec) rc2Params.getParameterSpec(RC2ParameterSpec.class); if (!rc2Spec.equals(rc2OtherSpec)) { throw new Exception("AlgorithmParameterSpecs should be equal"); } // test RC2ParameterSpec with RC2 Cipher Cipher rc2Cipher = Cipher.getInstance("RC2/CBC/PKCS5PADDING", "SunJCE"); rc2Cipher.init( Cipher.ENCRYPT_MODE, new SecretKeySpec("secret".getBytes("ASCII"), "RC2"), rc2Spec); // get IV byte[] iv = rc2Cipher.getIV(); if (!Arrays.equals(iv, rc2Spec.getIV())) { throw new Exception("ivs should be equal"); } // test encoding and decoding byte[] encoded = rc2Params.getEncoded(); AlgorithmParameters params = AlgorithmParameters.getInstance("RC2"); params.init(encoded); // test RC2 AlgorithmParameters with RC2 Cipher rc2Cipher.init( Cipher.ENCRYPT_MODE, new SecretKeySpec("secret".getBytes("ASCII"), "RC2"), params); // get IV iv = rc2Cipher.getIV(); if (!Arrays.equals(iv, rc2Spec.getIV())) { throw new Exception("ivs should be equal"); } return encoded; }
private void testGCMParameterSpecWithRepeatKey(byte[] K, byte[] N, byte[] A, byte[] P, byte[] C) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, NoSuchProviderException, IOException { Cipher eax = Cipher.getInstance("AES/EAX/NoPadding", "BC"); SecretKeySpec key = new SecretKeySpec(K, "AES"); GCMParameterSpec spec = new GCMParameterSpec(128, N); eax.init(Cipher.ENCRYPT_MODE, key, spec); eax.updateAAD(A); byte[] c = eax.doFinal(P); if (!areEqual(C, c)) { fail("JCE encrypt with additional data and RepeatedSecretKeySpec failed."); } // Check GCMParameterSpec handling knows about RepeatedSecretKeySpec eax.init(Cipher.DECRYPT_MODE, new RepeatedSecretKeySpec("AES"), spec); eax.updateAAD(A); byte[] p = eax.doFinal(C); if (!areEqual(P, p)) { fail("JCE decrypt with additional data and RepeatedSecretKeySpec failed."); } AlgorithmParameters algParams = eax.getParameters(); byte[] encParams = algParams.getEncoded(); GCMParameters gcmParameters = GCMParameters.getInstance(encParams); if (!Arrays.areEqual(spec.getIV(), gcmParameters.getNonce()) || spec.getTLen() != gcmParameters.getIcvLen()) { fail("parameters mismatch"); } }
/** * Constructs an <code>EncryptedPrivateKeyInfo</code> from the encryption algorithm parameters and * the encrypted data. * * <p>Note: the <code>encrypedData</code> is cloned when constructing this object. * * @param algParams the algorithm parameters for the encryption algorithm. <code> * algParams.getEncoded()</code> should return the ASN.1 encoded bytes of the <code>parameters * </code> field of the <code>AlgorithmIdentifer</code> component of the <code> * EncryptedPrivateKeyInfo</code> type. * @param encryptedData encrypted data. * @exception NullPointerException if <code>algParams</code> or <code>encryptedData</code> is * null. * @exception IllegalArgumentException if <code>encryptedData</code> is empty, i.e. 0-length. * @exception NoSuchAlgorithmException if the specified algName of the specified <code>algParams * </code> parameter is not supported. */ public EncryptedPrivateKeyInfo(AlgorithmParameters algParams, byte[] encryptedData) throws NullPointerException, IllegalArgumentException, NoSuchAlgorithmException { if (algParams == null || encryptedData == null) { throw new NullPointerException("parameters null"); } org.bouncycastle.asn1.x509.AlgorithmIdentifier kAlgId = null; try { ByteArrayInputStream bIn = new ByteArrayInputStream(algParams.getEncoded()); ASN1InputStream dIn = new ASN1InputStream(bIn); kAlgId = new AlgorithmIdentifier( new DERObjectIdentifier(algParams.getAlgorithm()), dIn.readObject()); } catch (IOException e) { throw new IllegalArgumentException("error in encoding: " + e.toString()); } infoObj = new org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo( kAlgId, (byte[]) encryptedData.clone()); algP = this.getParameters(); }
/** * Parse a DER stream into an X.509 certificate. * * @param encoded The encoded bytes. */ private void parse(InputStream encoded) throws Exception { DERReader der = new DERReader(encoded); // Certificate ::= SEQUENCE { DERValue cert = der.read(); debug("start Certificate len == " + cert.getLength()); this.encoded = cert.getEncoded(); if (!cert.isConstructed()) { throw new IOException("malformed Certificate"); } // TBSCertificate ::= SEQUENCE { DERValue tbsCert = der.read(); if (tbsCert.getValue() != DER.CONSTRUCTED_VALUE) { throw new IOException("malformed TBSCertificate"); } tbsCertBytes = tbsCert.getEncoded(); debug("start TBSCertificate len == " + tbsCert.getLength()); // Version ::= INTEGER [0] { v1(0), v2(1), v3(2) } DERValue val = der.read(); if (val.getTagClass() == DER.CONTEXT && val.getTag() == 0) { version = ((BigInteger) der.read().getValue()).intValue() + 1; val = der.read(); } else { version = 1; } debug("read version == " + version); // SerialNumber ::= INTEGER serialNo = (BigInteger) val.getValue(); debug("read serial number == " + serialNo); // AlgorithmIdentifier ::= SEQUENCE { val = der.read(); if (!val.isConstructed()) { throw new IOException("malformed AlgorithmIdentifier"); } int certAlgLen = val.getLength(); debug("start AlgorithmIdentifier len == " + certAlgLen); val = der.read(); // algorithm OBJECT IDENTIFIER, algId = (OID) val.getValue(); debug("read algorithm ID == " + algId); // parameters ANY DEFINED BY algorithm OPTIONAL } if (certAlgLen > val.getEncodedLength()) { val = der.read(); if (val == null) { algVal = null; } else { algVal = val.getEncoded(); } if (val.isConstructed()) { encoded.skip(val.getLength()); } debug("read algorithm parameters == " + algVal); } // issuer Name, val = der.read(); issuer = new X500Name(val.getEncoded()); der.skip(val.getLength()); debug("read issuer == " + issuer); // Validity ::= SEQUENCE { // notBefore Time, // notAfter Time } if (!der.read().isConstructed()) { throw new IOException("malformed Validity"); } notBefore = (Date) der.read().getValue(); notAfter = (Date) der.read().getValue(); debug("read notBefore == " + notBefore); debug("read notAfter == " + notAfter); // subject Name, val = der.read(); subject = new X500Name(val.getEncoded()); der.skip(val.getLength()); debug("read subject == " + subject); // SubjectPublicKeyInfo ::= SEQUENCE { // algorithm AlgorithmIdentifier, // subjectPublicKey BIT STRING } DERValue spki = der.read(); if (!spki.isConstructed()) { throw new IOException("malformed SubjectPublicKeyInfo"); } KeyFactory spkFac = KeyFactory.getInstance("X.509"); subjectKey = spkFac.generatePublic(new X509EncodedKeySpec(spki.getEncoded())); der.skip(spki.getLength()); debug("read subjectPublicKey == " + subjectKey); if (version > 1) { val = der.read(); } if (version >= 2 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 1) { byte[] b = (byte[]) val.getValue(); issuerUniqueId = new BitString(b, 1, b.length - 1, b[0] & 0xFF); debug("read issuerUniqueId == " + issuerUniqueId); val = der.read(); } if (version >= 2 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 2) { byte[] b = (byte[]) val.getValue(); subjectUniqueId = new BitString(b, 1, b.length - 1, b[0] & 0xFF); debug("read subjectUniqueId == " + subjectUniqueId); val = der.read(); } if (version >= 3 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 3) { val = der.read(); debug("start Extensions len == " + val.getLength()); int len = 0; while (len < val.getLength()) { DERValue ext = der.read(); debug("start extension len == " + ext.getLength()); Extension e = new Extension(ext.getEncoded()); extensions.put(e.getOid(), e); der.skip(ext.getLength()); len += ext.getEncodedLength(); debug("count == " + len); } } val = der.read(); if (!val.isConstructed()) { throw new IOException("malformed AlgorithmIdentifier"); } int sigAlgLen = val.getLength(); debug("start AlgorithmIdentifier len == " + sigAlgLen); val = der.read(); sigAlgId = (OID) val.getValue(); debug("read algorithm id == " + sigAlgId); if (sigAlgLen > val.getEncodedLength()) { val = der.read(); if (val.getValue() == null) { if (subjectKey instanceof DSAPublicKey) { AlgorithmParameters params = AlgorithmParameters.getInstance("DSA"); DSAParams dsap = ((DSAPublicKey) subjectKey).getParams(); DSAParameterSpec spec = new DSAParameterSpec(dsap.getP(), dsap.getQ(), dsap.getG()); params.init(spec); sigAlgVal = params.getEncoded(); } } else { sigAlgVal = (byte[]) val.getEncoded(); } if (val.isConstructed()) { encoded.skip(val.getLength()); } debug("read parameters == " + sigAlgVal); } signature = ((BitString) der.read().getValue()).toByteArray(); debug("read signature ==\n" + Util.hexDump(signature, ">>>> ")); }
public OutputEncryptor build() throws OperatorCreationException { final AlgorithmIdentifier algID; salt = new byte[20]; if (random == null) { random = new SecureRandom(); } random.nextBytes(salt); try { this.cipher = helper.createCipher(algOID.getId()); if (PEMUtilities.isPKCS5Scheme2(algOID)) { this.paramGen = helper.createAlgorithmParameterGenerator(algOID.getId()); } else { this.secKeyFact = helper.createSecretKeyFactory(algOID.getId()); } } catch (GeneralSecurityException e) { throw new OperatorCreationException(algOID + " not available: " + e.getMessage(), e); } if (PEMUtilities.isPKCS5Scheme2(algOID)) { params = paramGen.generateParameters(); try { KeyDerivationFunc scheme = new KeyDerivationFunc(algOID, ASN1Primitive.fromByteArray(params.getEncoded())); KeyDerivationFunc func = new KeyDerivationFunc( PKCSObjectIdentifiers.id_PBKDF2, new PBKDF2Params(salt, iterationCount)); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(func); v.add(scheme); algID = new AlgorithmIdentifier( PKCSObjectIdentifiers.id_PBES2, PBES2Parameters.getInstance(new DERSequence(v))); } catch (IOException e) { throw new OperatorCreationException(e.getMessage(), e); } key = PEMUtilities.generateSecretKeyForPKCS5Scheme2( algOID.getId(), password, salt, iterationCount); try { cipher.init(Cipher.ENCRYPT_MODE, key, params); } catch (GeneralSecurityException e) { throw new OperatorCreationException(e.getMessage(), e); } } else if (PEMUtilities.isPKCS12(algOID)) { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DEROctetString(salt)); v.add(new ASN1Integer(iterationCount)); algID = new AlgorithmIdentifier(algOID, PKCS12PBEParams.getInstance(new DERSequence(v))); try { PBEKeySpec pbeSpec = new PBEKeySpec(password); PBEParameterSpec defParams = new PBEParameterSpec(salt, iterationCount); key = secKeyFact.generateSecret(pbeSpec); cipher.init(Cipher.ENCRYPT_MODE, key, defParams); } catch (GeneralSecurityException e) { throw new OperatorCreationException(e.getMessage(), e); } } else { throw new OperatorCreationException("unknown algorithm: " + algOID, null); } return new OutputEncryptor() { public AlgorithmIdentifier getAlgorithmIdentifier() { return algID; } public OutputStream getOutputStream(OutputStream encOut) { return new CipherOutputStream(encOut, cipher); } public GenericKey getKey() { return new JceGenericKey(algID, key); } }; }
public void performTest() throws Exception { KeyFactory fact; byte[] input = new byte[] { (byte) 0x54, (byte) 0x85, (byte) 0x9b, (byte) 0x34, (byte) 0x2c, (byte) 0x49, (byte) 0xea, (byte) 0x2a }; byte[][] output = new byte[][] { Hex.decode( "8b427f781a2e59dd9def386f1956b996ee07f48c96880e65a368055ed8c0a8831669ef7250b40918b2b1d488547e72c84540e42bd07b03f14e226f04fbc2d929"), Hex.decode( "2ec6e1a1711b6c7b8cd3f6a25db21ab8bb0a5f1d6df2ef375fa708a43997730ffc7c98856dbbe36edddcdd1b2d2a53867d8355af94fea3aeec128da908e08f4c"), Hex.decode( "0850ac4e5a8118323200c8ed1e5aaa3d5e635172553ccac66a8e4153d35c79305c4440f11034ab147fccce21f18a50cf1c0099c08a577eb68237a91042278965"), Hex.decode( "1c9649bdccb51056751fe43837f4eb43bada472accf26f65231666d5de7d11950d8379b3596dfdf75c6234274896fa8d18ad0865d3be2ac4d6687151abdf01e93941dcef18fa63186c9351d1506c89d09733c5ff4304208c812bdd21a50f56fde115e629e0e973721c9fcc87e89295a79853dee613962a0b2f2fc57163fd99057a3c776f13c20c26407eb8863998d7e53b543ba8d0a295a9a68d1a149833078c9809ad6a6dad7fc22a95ad615a73138c54c018f40d99bf8eeecd45f5be526f2d6b01aeb56381991c1ab31a2e756f15e052b9cd5638b2eff799795c5bae493307d5eb9f8c21d438de131fe505a4e7432547ab19224094f9e4be1968bd0793b79d"), Hex.decode( "4c4afc0c24dddaedd4f9a3b23be30d35d8e005ffd36b3defc5d18acc830c3ed388ce20f43a00e614fd087c814197bc9fc2eff9ad4cc474a7a2ef3ed9c0f0a55eb23371e41ee8f2e2ed93ea3a06ca482589ab87e0d61dcffda5eea1241408e43ea1108726cdb87cc3aa5e9eaaa9f72507ca1352ac54a53920c94dccc768147933d8c50aefd9d1da10522a40133cd33dbc0524669e70f771a88d65c4716d471cd22b08b9f01f24e4e9fc7ffbcfa0e0a7aed47b345826399b26a73be112eb9c5e06fc6742fc3d0ef53d43896403c5105109cfc12e6deeaf4a48ba308e039774b9bdb31a9b9e133c81c321630cf0b4b2d1f90717b24c3268e1fea681ea9cdc709342"), Hex.decode( "06b5b26bd13515f799e5e37ca43cace15cd82fd4bf36b25d285a6f0998d97c8cb0755a28f0ae66618b1cd03e27ac95eaaa4882bc6dc0078cd457d4f7de4154173a9c7a838cfc2ac2f74875df462aae0cfd341645dc51d9a01da9bdb01507f140fa8a016534379d838cc3b2a53ac33150af1b242fc88013cb8d914e66c8182864ee6de88ce2879d4c05dd125409620a96797c55c832fb2fb31d4310c190b8ed2c95fdfda2ed87f785002faaec3f35ec05cf70a3774ce185e4882df35719d582dd55ac31257344a9cba95189dcbea16e8c6cb7a235a0384bc83b6183ca8547e670fe33b1b91725ae0c250c9eca7b5ba78bd77145b70270bf8ac31653006c02ca9c"), Hex.decode( "135f1be3d045526235bf9d5e43499d4ee1bfdf93370769ae56e85dbc339bc5b7ea3bee49717497ee8ac3f7cd6adb6fc0f17812390dcd65ac7b87fef7970d9ff9"), Hex.decode( "03c05add1e030178c352face07cafc9447c8f369b8f95125c0d311c16b6da48ca2067104cce6cd21ae7b163cd18ffc13001aecebdc2eb02b9e92681f84033a98"), Hex.decode( "00319bb9becb49f3ed1bca26d0fcf09b0b0a508e4d0bd43b350f959b72cd25b3af47d608fdcd248eada74fbe19990dbeb9bf0da4b4e1200243a14e5cab3f7e610c") }; SecureRandom rand = new FixedSecureRandom(); fact = KeyFactory.getInstance("RSA", "BC"); PrivateKey privKey = fact.generatePrivate(privKeySpec); PublicKey pubKey = fact.generatePublic(pubKeySpec); PrivateKey priv2048Key = fact.generatePrivate(priv2048KeySpec); PublicKey pub2048Key = fact.generatePublic(pub2048KeySpec); // // key without CRT coefficients // PrivateKeyInfo keyInfo = PrivateKeyInfo.getInstance(privKey.getEncoded()); BigInteger zero = BigInteger.valueOf(0); PKCS8EncodedKeySpec noCrtSpec = new PKCS8EncodedKeySpec( new PrivateKeyInfo( keyInfo.getPrivateKeyAlgorithm(), new org.mightyfish.asn1.pkcs.RSAPrivateKey( privKeySpec.getModulus(), privKeySpec.getPublicExponent(), privKeySpec.getPrivateExponent(), zero, zero, zero, zero, zero)) .getEncoded()); PrivateKey noCrtKey = fact.generatePrivate(noCrtSpec); if (noCrtKey instanceof RSAPrivateCrtKey) { fail("private key without CRT coefficients returned as CRT key"); } // // No Padding // Cipher c = Cipher.getInstance("RSA", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); byte[] out = c.doFinal(input); if (!areEqual(out, output[0])) { fail( "NoPadding test failed on encrypt expected " + new String(Hex.encode(output[0])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail( "NoPadding test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // No Padding - incremental // c = Cipher.getInstance("RSA", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); c.update(input); out = c.doFinal(); if (!areEqual(out, output[0])) { fail( "NoPadding test failed on encrypt expected " + new String(Hex.encode(output[0])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail( "NoPadding test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // No Padding - incremental - explicit use of NONE in mode. // c = Cipher.getInstance("RSA/NONE/NoPadding", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); c.update(input); out = c.doFinal(); if (!areEqual(out, output[0])) { fail( "NoPadding test failed on encrypt expected " + new String(Hex.encode(output[0])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail( "NoPadding test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // No Padding - maximum length // c = Cipher.getInstance("RSA", "BC"); byte[] modBytes = ((RSAPublicKey) pubKey).getModulus().toByteArray(); byte[] maxInput = new byte[modBytes.length - 1]; maxInput[0] |= 0x7f; c.init(Cipher.ENCRYPT_MODE, pubKey, rand); out = c.doFinal(maxInput); c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, maxInput)) { fail( "NoPadding test failed on decrypt expected " + new String(Hex.encode(maxInput)) + " got " + new String(Hex.encode(out))); } // // PKCS1 V 1.5 // c = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); out = c.doFinal(input); if (!areEqual(out, output[1])) { fail( "PKCS1 test failed on encrypt expected " + new String(Hex.encode(output[1])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail( "PKCS1 test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // PKCS1 V 1.5 - NONE // c = Cipher.getInstance("RSA/NONE/PKCS1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); out = c.doFinal(input); if (!areEqual(out, output[1])) { fail( "PKCS1 test failed on encrypt expected " + new String(Hex.encode(output[1])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail( "PKCS1 test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // OAEP - SHA1 // c = Cipher.getInstance("RSA/NONE/OAEPPadding", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); out = c.doFinal(input); if (!areEqual(out, output[2])) { fail( "OAEP test failed on encrypt expected " + new String(Hex.encode(output[2])) + " got " + new String(Hex.encode(out))); } c = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding", "BC"); c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail( "OAEP test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } AlgorithmParameters oaepP = c.getParameters(); if (!areEqual( oaepP.getEncoded(), new RSAESOAEPparams( new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE), new AlgorithmIdentifier( PKCSObjectIdentifiers.id_mgf1, new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE)), new AlgorithmIdentifier( PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0]))) .getEncoded())) { fail("OAEP test failed default sha-1 parameters"); } // // OAEP - SHA224 // c = Cipher.getInstance("RSA/NONE/OAEPWithSHA224AndMGF1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, pub2048Key, rand); out = c.doFinal(input); if (!areEqual(out, output[3])) { fail( "OAEP SHA-224 test failed on encrypt expected " + new String(Hex.encode(output[2])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, priv2048Key); out = c.doFinal(out); if (!areEqual(out, input)) { fail( "OAEP SHA-224 test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } oaepP = c.getParameters(); if (!areEqual( oaepP.getEncoded(), new RSAESOAEPparams( new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE), new AlgorithmIdentifier( PKCSObjectIdentifiers.id_mgf1, new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, DERNull.INSTANCE)), new AlgorithmIdentifier( PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0]))) .getEncoded())) { fail("OAEP test failed default sha-224 parameters"); } // // OAEP - SHA 256 // c = Cipher.getInstance("RSA/NONE/OAEPWithSHA256AndMGF1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, pub2048Key, rand); out = c.doFinal(input); if (!areEqual(out, output[4])) { fail( "OAEP SHA-256 test failed on encrypt expected " + new String(Hex.encode(output[2])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, priv2048Key); out = c.doFinal(out); if (!areEqual(out, input)) { fail( "OAEP SHA-256 test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } oaepP = c.getParameters(); if (!areEqual( oaepP.getEncoded(), new RSAESOAEPparams( new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE), new AlgorithmIdentifier( PKCSObjectIdentifiers.id_mgf1, new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE)), new AlgorithmIdentifier( PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0]))) .getEncoded())) { fail("OAEP test failed default sha-256 parameters"); } // // OAEP - SHA 384 // c = Cipher.getInstance("RSA/NONE/OAEPWithSHA384AndMGF1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, pub2048Key, rand); out = c.doFinal(input); if (!areEqual(out, output[5])) { fail( "OAEP SHA-384 test failed on encrypt expected " + new String(Hex.encode(output[2])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, priv2048Key); out = c.doFinal(out); if (!areEqual(out, input)) { fail( "OAEP SHA-384 test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } oaepP = c.getParameters(); if (!areEqual( oaepP.getEncoded(), new RSAESOAEPparams( new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE), new AlgorithmIdentifier( PKCSObjectIdentifiers.id_mgf1, new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, DERNull.INSTANCE)), new AlgorithmIdentifier( PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0]))) .getEncoded())) { fail("OAEP test failed default sha-384 parameters"); } // // OAEP - MD5 // c = Cipher.getInstance("RSA/NONE/OAEPWithMD5AndMGF1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); out = c.doFinal(input); if (!areEqual(out, output[6])) { fail( "OAEP MD5 test failed on encrypt expected " + new String(Hex.encode(output[2])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail( "OAEP MD5 test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } oaepP = c.getParameters(); if (!areEqual( oaepP.getEncoded(), new RSAESOAEPparams( new AlgorithmIdentifier(PKCSObjectIdentifiers.md5, DERNull.INSTANCE), new AlgorithmIdentifier( PKCSObjectIdentifiers.id_mgf1, new AlgorithmIdentifier(PKCSObjectIdentifiers.md5, DERNull.INSTANCE)), new AlgorithmIdentifier( PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[0]))) .getEncoded())) { fail("OAEP test failed default md5 parameters"); } // // OAEP - SHA1 with default parameters // c = Cipher.getInstance("RSA/NONE/OAEPPadding", "BC"); c.init(Cipher.ENCRYPT_MODE, pubKey, OAEPParameterSpec.DEFAULT, rand); out = c.doFinal(input); if (!areEqual(out, output[2])) { fail( "OAEP test failed on encrypt expected " + new String(Hex.encode(output[2])) + " got " + new String(Hex.encode(out))); } c = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding", "BC"); c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail( "OAEP test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } oaepP = c.getParameters(); if (!areEqual(oaepP.getEncoded(), new byte[] {0x30, 0x00})) { fail("OAEP test failed default parameters"); } // // OAEP - SHA1 with specified string // c = Cipher.getInstance("RSA/NONE/OAEPPadding", "BC"); c.init( Cipher.ENCRYPT_MODE, pubKey, new OAEPParameterSpec( "SHA1", "MGF1", new MGF1ParameterSpec("SHA1"), new PSource.PSpecified(new byte[] {1, 2, 3, 4, 5})), rand); out = c.doFinal(input); oaepP = c.getParameters(); if (!areEqual( oaepP.getEncoded(), new RSAESOAEPparams( new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE), new AlgorithmIdentifier( PKCSObjectIdentifiers.id_mgf1, new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, DERNull.INSTANCE)), new AlgorithmIdentifier( PKCSObjectIdentifiers.id_pSpecified, new DEROctetString(new byte[] {1, 2, 3, 4, 5}))) .getEncoded())) { fail("OAEP test failed changed sha-1 parameters"); } if (!areEqual(out, output[7])) { fail( "OAEP test failed on encrypt expected " + new String(Hex.encode(output[2])) + " got " + new String(Hex.encode(out))); } c = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Padding", "BC"); c.init(Cipher.DECRYPT_MODE, privKey, oaepP); out = c.doFinal(out); if (!areEqual(out, input)) { fail( "OAEP test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // ISO9796-1 // byte[] isoInput = Hex.decode("fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210"); PrivateKey isoPrivKey = fact.generatePrivate(isoPrivKeySpec); PublicKey isoPubKey = fact.generatePublic(isoPubKeySpec); c = Cipher.getInstance("RSA/NONE/ISO9796-1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, isoPrivKey); out = c.doFinal(isoInput); if (!areEqual(out, output[8])) { fail( "ISO9796-1 test failed on encrypt expected " + new String(Hex.encode(output[3])) + " got " + new String(Hex.encode(out))); } c.init(Cipher.DECRYPT_MODE, isoPubKey); out = c.doFinal(out); if (!areEqual(out, isoInput)) { fail( "ISO9796-1 test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // // generation with parameters test. // KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA", "BC"); // // 768 bit RSA with e = 2^16-1 // keyPairGen.initialize( new RSAKeyGenParameterSpec(768, BigInteger.valueOf(65537)), new SecureRandom()); KeyPair kp = keyPairGen.generateKeyPair(); pubKey = kp.getPublic(); privKey = kp.getPrivate(); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); out = c.doFinal(input); c.init(Cipher.DECRYPT_MODE, privKey); out = c.doFinal(out); if (!areEqual(out, input)) { fail( "key generation test failed on decrypt expected " + new String(Hex.encode(input)) + " got " + new String(Hex.encode(out))); } // // comparison check // KeyFactory keyFact = KeyFactory.getInstance("RSA", "BC"); RSAPrivateCrtKey crtKey = (RSAPrivateCrtKey) keyFact.translateKey(privKey); if (!privKey.equals(crtKey)) { fail("private key equality check failed"); } crtKey = (RSAPrivateCrtKey) keyFact.generatePrivate(new PKCS8EncodedKeySpec(privKey.getEncoded())); if (!privKey.equals(crtKey)) { fail("private key equality check failed"); } crtKey = (RSAPrivateCrtKey) serializeDeserialize(privKey); if (!privKey.equals(crtKey)) { fail("private key equality check failed"); } if (privKey.hashCode() != crtKey.hashCode()) { fail("private key hashCode check failed"); } RSAPublicKey copyKey = (RSAPublicKey) keyFact.translateKey(pubKey); if (!pubKey.equals(copyKey)) { fail("public key equality check failed"); } copyKey = (RSAPublicKey) keyFact.generatePublic(new X509EncodedKeySpec(pubKey.getEncoded())); if (!pubKey.equals(copyKey)) { fail("public key equality check failed"); } copyKey = (RSAPublicKey) serializeDeserialize(pubKey); if (!pubKey.equals(copyKey)) { fail("public key equality check failed"); } if (pubKey.hashCode() != copyKey.hashCode()) { fail("public key hashCode check failed"); } // // test an OAEP key // SubjectPublicKeyInfo oaepKey = new SubjectPublicKeyInfo( new AlgorithmIdentifier(PKCSObjectIdentifiers.id_RSAES_OAEP, new RSAESOAEPparams()), SubjectPublicKeyInfo.getInstance(pubKey.getEncoded()).parsePublicKey()); copyKey = (RSAPublicKey) serializeDeserialize( keyFact.generatePublic(new X509EncodedKeySpec(oaepKey.getEncoded()))); if (!pubKey.equals(copyKey)) { fail("public key equality check failed"); } if (pubKey.hashCode() != copyKey.hashCode()) { fail("public key hashCode check failed"); } if (!Arrays.areEqual(copyKey.getEncoded(), oaepKey.getEncoded())) { fail("encoding does not match"); } oaepCompatibilityTest("SHA-1", priv2048Key, pub2048Key); // TODO: oaepCompatibilityTest("SHA-224", priv2048Key, pub2048Key); commented out as fails // in JDK 1.7 oaepCompatibilityTest("SHA-256", priv2048Key, pub2048Key); oaepCompatibilityTest("SHA-384", priv2048Key, pub2048Key); oaepCompatibilityTest("SHA-512", priv2048Key, pub2048Key); SecureRandom random = new SecureRandom(); rawModeTest("SHA1withRSA", X509ObjectIdentifiers.id_SHA1, priv2048Key, pub2048Key, random); rawModeTest("MD5withRSA", PKCSObjectIdentifiers.md5, priv2048Key, pub2048Key, random); rawModeTest( "RIPEMD128withRSA", TeleTrusTObjectIdentifiers.ripemd128, priv2048Key, pub2048Key, random); // init reset test c.init(Cipher.ENCRYPT_MODE, pubKey, rand); out = c.update(new byte[40]); c.init(Cipher.ENCRYPT_MODE, pubKey, rand); out = c.update(new byte[40]); }
public void performTest() throws Exception { KeyFactory fact = KeyFactory.getInstance("RSA", "SC"); PrivateKey privKey = fact.generatePrivate(privKeySpec); PublicKey pubKey = fact.generatePublic(pubKeySpec); Signature s = Signature.getInstance("SHA1withRSA/PSS", "SC"); s.initSign(privKey, new FixedRandom(slt1a)); s.update(msg1a); byte[] sig = s.sign(); if (!arrayEquals(sig1a, sig)) { fail( "PSS Sign test expected " + new String(Hex.encode(sig1a)) + " got " + new String(Hex.encode(sig))); } s = Signature.getInstance("SHA1withRSAandMGF1", "SC"); s.initVerify(pubKey); s.update(msg1a); if (!s.verify(sig1a)) { fail("SHA1 signature verification failed"); } s = Signature.getInstance("SHA1withRSAandMGF1", "SC"); s.setParameter(PSSParameterSpec.DEFAULT); s.initVerify(pubKey); s.update(msg1a); if (!s.verify(sig1a)) { fail("SHA1 signature verification with default parameters failed"); } AlgorithmParameters pss = s.getParameters(); if (!arrayEquals(pss.getEncoded(), new byte[] {0x30, 0x00})) { fail("failed default encoding test."); } s = Signature.getInstance("SHA256withRSA/PSS", "SC"); s.initSign(privKey, new FixedRandom(slt1a)); s.update(msg1a); sig = s.sign(); pss = s.getParameters(); if (!arrayEquals(sig1b, sig)) { fail( "PSS Sign test expected " + new String(Hex.encode(sig1b)) + " got " + new String(Hex.encode(sig))); } s = Signature.getInstance("SHA256withRSAandMGF1", "SC"); s.setParameter(pss.getParameterSpec(PSSParameterSpec.class)); s.initVerify(pubKey); s.update(msg1a); if (!s.verify(sig1b)) { fail("SHA256 signature verification failed"); } // // 512 test -with zero salt length // s = Signature.getInstance("SHA512withRSAandMGF1", "SC"); s.setParameter(new PSSParameterSpec("SHA-512", "MGF1", new MGF1ParameterSpec("SHA-512"), 0, 1)); s.initSign(privKey); s.update(msg1a); sig = s.sign(); pss = s.getParameters(); if (!arrayEquals(sig1c, sig)) { fail( "PSS Sign test expected " + new String(Hex.encode(sig1c)) + " got " + new String(Hex.encode(sig))); } s = Signature.getInstance("SHA512withRSAandMGF1", "SC"); s.setParameter(pss.getParameterSpec(PSSParameterSpec.class)); s.initVerify(pubKey); s.update(msg1a); if (!s.verify(sig1c)) { fail("SHA512 signature verification failed"); } SecureRandom random = new SecureRandom(); // Note: PSS minimum key size determined by hash/salt lengths PrivateKey priv2048Key = fact.generatePrivate(RSATest.priv2048KeySpec); PublicKey pub2048Key = fact.generatePublic(RSATest.pub2048KeySpec); rawModeTest("SHA1withRSA/PSS", X509ObjectIdentifiers.id_SHA1, priv2048Key, pub2048Key, random); rawModeTest( "SHA224withRSA/PSS", NISTObjectIdentifiers.id_sha224, priv2048Key, pub2048Key, random); rawModeTest( "SHA256withRSA/PSS", NISTObjectIdentifiers.id_sha256, priv2048Key, pub2048Key, random); rawModeTest( "SHA384withRSA/PSS", NISTObjectIdentifiers.id_sha384, priv2048Key, pub2048Key, random); rawModeTest( "SHA512withRSA/PSS", NISTObjectIdentifiers.id_sha512, priv2048Key, pub2048Key, random); }