AlgorithmParameters implGetParameters() { AlgorithmParameters params = null; if (salt == null) { // Cipher is not initialized with parameters; // follow the recommendation in PKCS12 v1.0 // section B.4 to generate salt and iCount. salt = new byte[DEFAULT_SALT_LENGTH]; SunJCE.getRandom().nextBytes(salt); iCount = DEFAULT_COUNT; } PBEParameterSpec pbeSpec = new PBEParameterSpec(salt, iCount); try { params = AlgorithmParameters.getInstance(pbeAlgo, "SunJCE"); } catch (GeneralSecurityException gse) { // should never happen throw new RuntimeException("SunJCE provider is not configured properly"); } try { params.init(pbeSpec); } catch (InvalidParameterSpecException ipse) { // should never happen throw new RuntimeException("PBEParameterSpec not supported"); } return params; }
private void setSignatureParameters(Signature var1, DEREncodable var2) throws NoSuchAlgorithmException, SignatureException, InvalidKeyException { if (var2 != null) { if (!DERNull.INSTANCE.equals(var2)) { String var3 = var1.getAlgorithm(); Provider var4 = var1.getProvider(); AlgorithmParameters var5 = AlgorithmParameters.getInstance(var3, var4); try { byte[] var6 = var2.getDERObject().getDEREncoded(); var5.init(var6); } catch (IOException var17) { StringBuilder var9 = (new StringBuilder()).append("IOException decoding parameters: "); String var10 = var17.getMessage(); String var11 = var9.append(var10).toString(); throw new SignatureException(var11); } if (var1.getAlgorithm().endsWith("MGF1")) { try { AlgorithmParameterSpec var7 = var5.getParameterSpec(PSSParameterSpec.class); var1.setParameter(var7); } catch (GeneralSecurityException var16) { StringBuilder var13 = (new StringBuilder()).append("Exception extracting parameters: "); String var14 = var16.getMessage(); String var15 = var13.append(var14).toString(); throw new SignatureException(var15); } } } } }
/** * Generate a spec from a curve name * * @return null if fail */ private static ECParameterSpec genSpec(String name) { // convert the ECGenParameterSpecs to ECParameterSpecs for several reasons: // 1) to check availability // 2) efficiency // 3) SigUtil must cast the AlgorithmParameterSpec to a ECParameterSpec // to convert a I2P key to a Java key. Sadly, a ECGenParameterSpec // is not a ECParameterSpec. try { AlgorithmParameters ap; try { ap = AlgorithmParameters.getInstance("EC"); } catch (Exception e) { if (BC_AVAILABLE) { log("Named curve " + name + " is not available, trying BC", e); ap = AlgorithmParameters.getInstance("EC", "BC"); log("Fallback to BC worked for named curve " + name); } else { throw e; } } ECGenParameterSpec ecgps = new ECGenParameterSpec(name); ap.init(ecgps); ECParameterSpec rv = ap.getParameterSpec(ECParameterSpec.class); log("Named curve " + name + " loaded"); return rv; } catch (Exception e) { log("Named curve " + name + " is not available", e); return null; } }
/** * @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)); }
/** * Method getAlgParam. * * @return AlgorithmParameters * @param jceName The name of the algorithm parameters which may depend on the provider */ public AlgorithmParameters getAlgParam(String jceName) throws NoSuchAlgorithmException, IOException { if (this.param == null) { return null; } AlgorithmParameters ap = AlgorithmParameters.getInstance(jceName); ap.init(this.param.getValue()); return ap; }
public AlgorithmParameters getAlgParameters() { if (params == null && encodedParams != null) { try { params = AlgorithmParameters.getInstance(getAlgName()); params.init(encodedParams); } catch (NoSuchAlgorithmException ignore) { // FIXME throw exception? } catch (IOException ignore) { } } return params; }
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; }
public void testAES256CCM() throws Exception { byte[] data = "Eric H. Echidna".getBytes(); ASN1ObjectIdentifier macAlg = CMSAlgorithm.AES256_CCM; AlgorithmParameters algParams = AlgorithmParameters.getInstance("CCM", BC); algParams.init(new CCMParameters(Hex.decode("000102030405060708090a0b"), 16).getEncoded()); CMSAuthenticatedDataGenerator adGen = new CMSAuthenticatedDataGenerator(); X509CertificateHolder origCert = new X509CertificateHolder(_origCert.getEncoded()); adGen.setOriginatorInfo(new OriginatorInfoGenerator(origCert).generate()); adGen.addRecipientInfoGenerator( new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC)); CMSAuthenticatedData ad = adGen.generate( new CMSProcessableByteArray(data), new JceCMSMacCalculatorBuilder(macAlg) .setAlgorithmParameters(algParams) .setProvider(BC) .build()); assertTrue(ad.getOriginatorInfo().getCertificates().getMatches(null).contains(origCert)); RecipientInformationStore recipients = ad.getRecipientInfos(); assertEquals(ad.getMacAlgOID(), macAlg.getId()); Collection c = recipients.getRecipients(); assertEquals(1, c.size()); Iterator it = c.iterator(); while (it.hasNext()) { RecipientInformation recipient = (RecipientInformation) it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), PKCSObjectIdentifiers.rsaEncryption.getId()); byte[] recData = recipient.getContent( new JceKeyTransAuthenticatedRecipient(_reciKP.getPrivate()).setProvider(BC)); assertTrue(Arrays.equals(data, recData)); assertEquals(16, ad.getMac().length); assertTrue(Arrays.equals(ad.getMac(), recipient.getMac())); } }
protected AlgorithmParameters engineGetParameters() { if (engineParams == null) { if (paramSpec != null) { try { engineParams = helper.createAlgorithmParameters("OAEP"); engineParams.init(paramSpec); } catch (Exception e) { throw new RuntimeException(e.toString()); } } } return engineParams; }
protected AlgorithmParameters engineGetParameters() { if (engineParams == null) { if (paramSpec != null) { try { engineParams = AlgorithmParameters.getInstance("OAEP", "DFBC"); engineParams.init(paramSpec); } catch (Exception e) { throw new RuntimeException(e.toString()); } } } return engineParams; }
/* * Generate PBE Algorithm Parameters */ private AlgorithmParameters getAlgorithmParameters(String algorithm) throws IOException { AlgorithmParameters algParams = null; // create PBE parameters from salt and iteration count PBEParameterSpec paramSpec = new PBEParameterSpec(getSalt(), iterationCount); try { algParams = AlgorithmParameters.getInstance(algorithm); algParams.init(paramSpec); } catch (Exception e) { IOException ioe = new IOException("getAlgorithmParameters failed: " + e.getMessage()); ioe.initCause(e); throw ioe; } return algParams; }
// see JCE spec protected AlgorithmParameters engineGetParameters() { if (iv == null) { return null; } IvParameterSpec ivSpec = new IvParameterSpec(iv); try { AlgorithmParameters params = AlgorithmParameters.getInstance(keyAlgorithm, P11Util.getSunJceProvider()); params.init(ivSpec); return params; } catch (GeneralSecurityException e) { // NoSuchAlgorithmException, NoSuchProviderException // InvalidParameterSpecException throw new ProviderException("Could not encode parameters", e); } }
protected AlgorithmParameters engineGetParameters() { if (engineParam == null) { if (engineParams != null) { String name = "IES"; try { engineParam = AlgorithmParameters.getInstance(name, BouncyCastleProvider.PROVIDER_NAME); engineParam.init(engineParams); } catch (Exception e) { throw new RuntimeException(e.toString()); } } } return engineParam; }
private AlgorithmParameters getParameters() throws NoSuchAlgorithmException { AlgorithmParameters ap = AlgorithmParameters.getInstance(this.getAlgName()); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); try { dOut.writeObject(infoObj.getEncryptionAlgorithm().getParameters()); dOut.close(); ap.init(bOut.toByteArray()); } catch (IOException e) { throw new NoSuchAlgorithmException("unable to parse parameters"); } return ap; }
private void tryKekAlgorithm(SecretKey kek, ASN1ObjectIdentifier algOid, byte[] encodedParameters) throws NoSuchAlgorithmException, NoSuchProviderException, CMSException, OperatorCreationException, IOException { byte[] data = "Eric H. Echidna".getBytes(); CMSAuthenticatedDataGenerator adGen = new CMSAuthenticatedDataGenerator(); byte[] kekId = new byte[] {1, 2, 3, 4, 5}; adGen.addRecipientInfoGenerator(new JceKEKRecipientInfoGenerator(kekId, kek).setProvider(BC)); AlgorithmParameters algParams = AlgorithmParameters.getInstance(CMSAlgorithm.DES_EDE3_CBC.getId(), "BC"); algParams.init(encodedParameters); CMSAuthenticatedData ad = adGen.generate( new CMSProcessableByteArray(data), new JceCMSMacCalculatorBuilder(CMSAlgorithm.DES_EDE3_CBC) .setAlgorithmParameters(algParams) .setProvider(BC) .build()); RecipientInformationStore recipients = ad.getRecipientInfos(); Collection c = recipients.getRecipients(); Iterator it = c.iterator(); assertEquals(ad.getMacAlgOID(), CMSAuthenticatedDataGenerator.DES_EDE3_CBC); assertEquals( ad.getMacAlgorithm().getParameters(), ASN1Primitive.fromByteArray(encodedParameters)); if (it.hasNext()) { RecipientInformation recipient = (RecipientInformation) it.next(); assertEquals(recipient.getKeyEncryptionAlgOID(), algOid.getId()); byte[] recData = recipient.getContent(new JceKEKAuthenticatedRecipient(kek).setProvider(BC)); assertTrue(Arrays.equals(data, recData)); assertTrue(Arrays.equals(ad.getMac(), recipient.getMac())); } else { fail("no recipient found"); } }
protected AlgorithmParameters engineGetParameters() { if (engineParams == null) { if (pbeSpec != null) { try { AlgorithmParameters engineParams = AlgorithmParameters.getInstance(pbeAlgorithm, BouncyCastleProvider.PROVIDER_NAME); engineParams.init(pbeSpec); return engineParams; } catch (Exception e) { return null; } } } return engineParams; }
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"); } }
/** * return an AlgorithmParameters object representing the parameters to the key derivation * algorithm to the recipient. * * @return AlgorithmParameters object, null if there aren't any. */ public AlgorithmParameters getKeyDerivationAlgParameters(Provider provider) { try { if (info.getKeyDerivationAlgorithm() != null) { DEREncodable params = info.getKeyDerivationAlgorithm().getParameters(); if (params != null) { AlgorithmParameters algP = AlgorithmParameters.getInstance( info.getKeyDerivationAlgorithm().getObjectId().toString(), provider); algP.init(params.getDERObject().getEncoded()); return algP; } } return null; } catch (Exception e) { throw new RuntimeException("exception getting encryption parameters " + e); } }
protected AlgorithmParameters engineGenerateParameters() { byte[] iv = new byte[8]; if (random == null) { random = new SecureRandom(); } random.nextBytes(iv); AlgorithmParameters params; try { params = AlgorithmParameters.getInstance("CAST5", BouncyCastleProvider.PROVIDER_NAME); params.init(new IvParameterSpec(iv)); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } return params; }
protected AlgorithmParameters engineGetParameters() { if (engineParams == null) { if (ivParam != null) { String name = cipher.getUnderlyingCipher().getAlgorithmName(); if (name.indexOf('/') >= 0) { name = name.substring(0, name.indexOf('/')); } try { engineParams = AlgorithmParameters.getInstance(name, BouncyCastleProvider.PROVIDER_NAME); engineParams.init(ivParam.getIV()); } catch (Exception e) { throw new RuntimeException(e.toString()); } } } return engineParams; }
protected AlgorithmParameters engineGenerateParameters() { byte[] iv = new byte[8]; if (random == null) { random = new SecureRandom(); } random.nextBytes(iv); AlgorithmParameters params; try { params = createParametersInstance("DES"); params.init(new IvParameterSpec(iv)); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } return params; }
/** * @tests javax.crypto.Cipher#getIV() * @tests javax.crypto.Cipher#init(int, java.security.Key, java.security.AlgorithmParameters) */ public void test_getIV() throws Exception { /* * If this test is changed, implement the following: * test_initILjava_security_KeyLjava_security_AlgorithmParameters() */ SecureRandom sr = new SecureRandom(); Cipher cipher = null; byte[] iv = new byte[8]; sr.nextBytes(iv); AlgorithmParameters ap = AlgorithmParameters.getInstance(algorithm); ap.init(iv, "RAW"); cipher = Cipher.getInstance(algorithm + "/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, cipherKey, ap); byte[] cipherIV = cipher.getIV(); assertTrue("IVs differ", Arrays.equals(cipherIV, iv)); }
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()); }
/* * parse Algorithm Parameters */ private AlgorithmParameters parseAlgParameters(DerInputStream in) throws IOException { AlgorithmParameters algParams = null; try { DerValue params; if (in.available() == 0) { params = null; } else { params = in.getDerValue(); if (params.tag == DerValue.tag_Null) { params = null; } } if (params != null) { algParams = AlgorithmParameters.getInstance("PBE"); algParams.init(params.toByteArray()); } } catch (Exception e) { IOException ioe = new IOException("parseAlgParameters failed: " + e.getMessage()); ioe.initCause(e); throw ioe; } return algParams; }
/** * Decrypts the specified encrypted Content Encryption Key (CEK). * * @param priv The private RSA key. Must not be {@code null}. * @param encryptedCEK The encrypted Content Encryption Key (CEK) to decrypt. Must not be {@code * null}. * @return The decrypted Content Encryption Key (CEK). * @throws RuntimeException If decryption failed. */ public static SecretKey decryptCEK(final RSAPrivateKey priv, final byte[] encryptedCEK) { try { AlgorithmParameters algp = AlgorithmParameters.getInstance("OAEP", new BouncyCastleProvider()); AlgorithmParameterSpec paramSpec = new OAEPParameterSpec( "SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT); algp.init(paramSpec); Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding", new BouncyCastleProvider()); cipher.init(Cipher.DECRYPT_MODE, priv, algp); return new SecretKeySpec(cipher.doFinal(encryptedCEK), "AES"); } catch (Exception e) { // java.security.NoSuchAlgorithmException // java.security.NoSuchPaddingException // java.security.InvalidKeyException // javax.crypto.IllegalBlockSizeException // javax.crypto.BadPaddingException throw new RuntimeException(e.getMessage(), e); } }
/** * 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, ">>>> ")); }
private void run(String mode) throws Exception { DHParameterSpec dhSkipParamSpec; if (mode.equals("GENERATE_DH_PARAMS")) { // Some central authority creates new DH parameters System.out.println("Creating Diffie-Hellman parameters (takes VERY long) ..."); AlgorithmParameterGenerator paramGen = AlgorithmParameterGenerator.getInstance("DH"); paramGen.init(512); AlgorithmParameters params = paramGen.generateParameters(); dhSkipParamSpec = (DHParameterSpec) params.getParameterSpec(DHParameterSpec.class); } else { // use some pre-generated, default DH parameters System.out.println("Using SKIP Diffie-Hellman parameters"); dhSkipParamSpec = new DHParameterSpec(skip1024Modulus, skip1024Base); } /* * Alice creates her own DH key pair, using the DH parameters from * above */ System.out.println("ALICE: Generate DH keypair ..."); KeyPairGenerator aliceKpairGen = KeyPairGenerator.getInstance("DH"); aliceKpairGen.initialize(dhSkipParamSpec); KeyPair aliceKpair = aliceKpairGen.generateKeyPair(); // Alice creates and initializes her DH KeyAgreement object System.out.println("ALICE: Initialization ..."); KeyAgreement aliceKeyAgree = KeyAgreement.getInstance("DH"); aliceKeyAgree.init(aliceKpair.getPrivate()); // Alice encodes her public key, and sends it over to Bob. byte[] alicePubKeyEnc = aliceKpair.getPublic().getEncoded(); /* * Let's turn over to Bob. Bob has received Alice's public key * in encoded format. * He instantiates a DH public key from the encoded key material. */ KeyFactory bobKeyFac = KeyFactory.getInstance("DH"); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(alicePubKeyEnc); PublicKey alicePubKey = bobKeyFac.generatePublic(x509KeySpec); /* * Bob gets the DH parameters associated with Alice's public key. * He must use the same parameters when he generates his own key * pair. */ DHParameterSpec dhParamSpec = ((DHPublicKey) alicePubKey).getParams(); // Bob creates his own DH key pair System.out.println("BOB: Generate DH keypair ..."); KeyPairGenerator bobKpairGen = KeyPairGenerator.getInstance("DH"); bobKpairGen.initialize(dhParamSpec); KeyPair bobKpair = bobKpairGen.generateKeyPair(); // Bob creates and initializes his DH KeyAgreement object System.out.println("BOB: Initialization ..."); KeyAgreement bobKeyAgree = KeyAgreement.getInstance("DH"); bobKeyAgree.init(bobKpair.getPrivate()); // Bob encodes his public key, and sends it over to Alice. byte[] bobPubKeyEnc = bobKpair.getPublic().getEncoded(); /* * Alice uses Bob's public key for the first (and only) phase * of her version of the DH * protocol. * Before she can do so, she has to instantiate a DH public key * from Bob's encoded key material. */ KeyFactory aliceKeyFac = KeyFactory.getInstance("DH"); x509KeySpec = new X509EncodedKeySpec(bobPubKeyEnc); PublicKey bobPubKey = aliceKeyFac.generatePublic(x509KeySpec); System.out.println("ALICE: Execute PHASE1 ..."); aliceKeyAgree.doPhase(bobPubKey, true); /* * Bob uses Alice's public key for the first (and only) phase * of his version of the DH * protocol. */ System.out.println("BOB: Execute PHASE1 ..."); bobKeyAgree.doPhase(alicePubKey, true); /* * At this stage, both Alice and Bob have completed the DH key * agreement protocol. * Both generate the (same) shared secret. */ byte[] aliceSharedSecret = aliceKeyAgree.generateSecret(); int aliceLen = aliceSharedSecret.length; byte[] bobSharedSecret = new byte[aliceLen]; int bobLen; try { // show example of what happens if you // provide an output buffer that is too short bobLen = bobKeyAgree.generateSecret(bobSharedSecret, 1); } catch (ShortBufferException e) { System.out.println(e.getMessage()); } // provide output buffer of required size bobLen = bobKeyAgree.generateSecret(bobSharedSecret, 0); System.out.println("Alice secret: " + toHexString(aliceSharedSecret)); System.out.println("Bob secret: " + toHexString(bobSharedSecret)); if (!java.util.Arrays.equals(aliceSharedSecret, bobSharedSecret)) throw new Exception("Shared secrets differ"); System.out.println("Shared secrets are the same"); /* * Now let's return the shared secret as a SecretKey object * and use it for encryption. First, we generate SecretKeys for the * "DES" algorithm (based on the raw shared secret data) and * then we use DES in ECB mode * as the encryption algorithm. DES in ECB mode does not require any * parameters. * * Then we use DES in CBC mode, which requires an initialization * vector (IV) parameter. In CBC mode, you need to initialize the * Cipher object with an IV, which can be supplied using the * javax.crypto.spec.IvParameterSpec class. Note that you have to use * the same IV for encryption and decryption: If you use a different * IV for decryption than you used for encryption, decryption will * fail. * * NOTE: If you do not specify an IV when you initialize the * Cipher object for encryption, the underlying implementation * will generate a random one, which you have to retrieve using the * javax.crypto.Cipher.getParameters() method, which returns an * instance of java.security.AlgorithmParameters. You need to transfer * the contents of that object (e.g., in encoded format, obtained via * the AlgorithmParameters.getEncoded() method) to the party who will * do the decryption. When initializing the Cipher for decryption, * the (reinstantiated) AlgorithmParameters object must be passed to * the Cipher.init() method. */ System.out.println("Return shared secret as SecretKey object ..."); // Bob // NOTE: The call to bobKeyAgree.generateSecret above reset the key // agreement object, so we call doPhase again prior to another // generateSecret call bobKeyAgree.doPhase(alicePubKey, true); SecretKey bobDesKey = bobKeyAgree.generateSecret("DES"); // Alice // NOTE: The call to aliceKeyAgree.generateSecret above reset the key // agreement object, so we call doPhase again prior to another // generateSecret call aliceKeyAgree.doPhase(bobPubKey, true); SecretKey aliceDesKey = aliceKeyAgree.generateSecret("DES"); /* * Bob encrypts, using DES in ECB mode */ Cipher bobCipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); bobCipher.init(Cipher.ENCRYPT_MODE, bobDesKey); byte[] cleartext = "This is just an example".getBytes(); byte[] ciphertext = bobCipher.doFinal(cleartext); /* * Alice decrypts, using DES in ECB mode */ Cipher aliceCipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); aliceCipher.init(Cipher.DECRYPT_MODE, aliceDesKey); byte[] recovered = aliceCipher.doFinal(ciphertext); if (!java.util.Arrays.equals(cleartext, recovered)) throw new Exception("DES in CBC mode recovered text is " + "different from cleartext"); System.out.println("DES in ECB mode recovered text is " + "same as cleartext"); /* * Bob encrypts, using DES in CBC mode */ bobCipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); bobCipher.init(Cipher.ENCRYPT_MODE, bobDesKey); cleartext = "This is just an example".getBytes(); ciphertext = bobCipher.doFinal(cleartext); // Retrieve the parameter that was used, and transfer it to Alice in // encoded format byte[] encodedParams = bobCipher.getParameters().getEncoded(); /* * Alice decrypts, using DES in CBC mode */ // Instantiate AlgorithmParameters object from parameter encoding // obtained from Bob AlgorithmParameters params = AlgorithmParameters.getInstance("DES"); params.init(encodedParams); aliceCipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); aliceCipher.init(Cipher.DECRYPT_MODE, aliceDesKey, params); recovered = aliceCipher.doFinal(ciphertext); if (!java.util.Arrays.equals(cleartext, recovered)) throw new Exception("DES in CBC mode recovered text is " + "different from cleartext"); System.out.println("DES in CBC mode recovered text is " + "same as cleartext"); }