public int generateBytes(byte[] out, int outOff, int len) throws DataLengthException, IllegalArgumentException { // TODO Create an ASN.1 class for this (RFC3278) // ECC-CMS-SharedInfo ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new AlgorithmIdentifier(algorithm, DERNull.INSTANCE)); v.add(new DERTaggedObject(true, 2, new DEROctetString(Pack.intToBigEndian(keySize)))); try { kdf.init(new KDFParameters(z, new DERSequence(v).getEncoded(ASN1Encoding.DER))); } catch (IOException e) { throw new IllegalArgumentException("unable to initialise kdf: " + e.getMessage()); } return kdf.generateBytes(out, outOff, len); }
protected KeyParameter deriveKey(int keyLen, byte[] C, byte[] PEH) { byte[] kdfInput = PEH; if (SingleHashMode) { kdfInput = Arrays.concatenate(C, PEH); Arrays.fill(PEH, (byte)0); } try { // Initialise the KDF kdf.init(new KDFParameters(kdfInput, null)); // Generate the secret key byte[] K = new byte[keyLen]; kdf.generateBytes(K, 0, K.length); // Return the ciphertext return new KeyParameter(K); } finally { Arrays.fill(kdfInput, (byte)0); } }
private void checkMask( int count, DerivationFunction kdf, byte[] seed, byte[] result) { byte[] data = new byte[result.length]; kdf.init(new KDFParameters(seed, new byte[0])); kdf.generateBytes(data, 0, data.length); if (!areEqual(result, data)) { fail("KDF2 failed generator test " + count); } }
public void init( DerivationParameters param) { if (!(param instanceof KDFParameters)) { throw new IllegalArgumentException("KDF parameters required for KDF2Generator"); } KDFParameters p = (KDFParameters)param; shared = p.getSharedSecret(); iv = p.getIV(); }
/** * Generate and encapsulate a random session key. * * @param out the output buffer for the encapsulated key. * @param outOff the offset for the output buffer. * @param keyLen the length of the random session key. * @return the random session key. */ public CipherParameters encrypt(byte[] out, int outOff, int keyLen) throws IllegalArgumentException { if (key.isPrivate()) { throw new IllegalArgumentException("Public key required for encryption"); } BigInteger n = key.getModulus(); BigInteger e = key.getExponent(); // Generate the ephemeral random and encode it BigInteger r = BigIntegers.createRandomInRange(ZERO, n.subtract(ONE), rnd); byte[] R = BigIntegers.asUnsignedByteArray((n.bitLength() + 7) / 8, r); // Encrypt the random and encode it BigInteger c = r.modPow(e, n); byte[] C = BigIntegers.asUnsignedByteArray((n.bitLength() + 7) / 8, c); System.arraycopy(C, 0, out, outOff, C.length); // Initialise the KDF kdf.init(new KDFParameters(R, null)); // Generate the secret key byte[] K = new byte[keyLen]; kdf.generateBytes(K, 0, K.length); return new KeyParameter(K); }
/** * Decrypt an encapsulated session key. * * @param in the input buffer for the encapsulated key. * @param inOff the offset for the input buffer. * @param inLen the length of the encapsulated key. * @param keyLen the length of the session key. * @return the session key. */ public CipherParameters decrypt(byte[] in, int inOff, int inLen, int keyLen) throws IllegalArgumentException { if (!key.isPrivate()) { throw new IllegalArgumentException("Private key required for decryption"); } BigInteger n = key.getModulus(); BigInteger d = key.getExponent(); // Decode the input byte[] C = new byte[inLen]; System.arraycopy(in, inOff, C, 0, C.length); BigInteger c = new BigInteger(1, C); // Decrypt the ephemeral random and encode it BigInteger r = c.modPow(d, n); byte[] R = BigIntegers.asUnsignedByteArray((n.bitLength() + 7) / 8, r); // Initialise the KDF kdf.init(new KDFParameters(R, null)); // Generate the secret key byte[] K = new byte[keyLen]; kdf.generateBytes(K, 0, K.length); return new KeyParameter(K); }
public void init( DerivationParameters param) { if (param instanceof KDFParameters) { KDFParameters p = (KDFParameters)param; shared = p.getSharedSecret(); otherInfo = p.getIV(); } else { throw new IllegalArgumentException("KDF parameters required for KDF2Generator"); } }
protected KeyParameter generateKey(BigInteger n, BigInteger r, int keyLen) { byte[] R = BigIntegers.asUnsignedByteArray((n.bitLength() + 7) / 8, r); // Initialise the KDF kdf.init(new KDFParameters(R, null)); // Generate the secret key byte[] K = new byte[keyLen]; kdf.generateBytes(K, 0, K.length); return new KeyParameter(K); }
public byte[] processBlock( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { if (forEncryption) { if (keyPairGenerator != null) { EphemeralKeyPair ephKeyPair = keyPairGenerator.generate(); this.privParam = ephKeyPair.getKeyPair().getPrivate(); this.V = ephKeyPair.getEncodedPublicKey(); } } else { if (keyParser != null) { ByteArrayInputStream bIn = new ByteArrayInputStream(in, inOff, inLen); try { this.pubParam = keyParser.readKey(bIn); } catch (IOException e) { throw new InvalidCipherTextException("unable to recover ephemeral public key: " + e.getMessage(), e); } int encLength = (inLen - bIn.available()); this.V = Arrays.copyOfRange(in, inOff, inOff + encLength); } } // Compute the common value and convert to byte array. agree.init(privParam); BigInteger z = agree.calculateAgreement(pubParam); byte[] Z = BigIntegers.asUnsignedByteArray(agree.getFieldSize(), z); // Create input to KDF. byte[] VZ; if (V.length != 0) { VZ = new byte[V.length + Z.length]; System.arraycopy(V, 0, VZ, 0, V.length); System.arraycopy(Z, 0, VZ, V.length, Z.length); } else { VZ = Z; } // Initialise the KDF. KDFParameters kdfParam = new KDFParameters(VZ, param.getDerivationV()); kdf.init(kdfParam); return forEncryption ? encryptBlock(in, inOff, inLen) : decryptBlock(in, inOff, inLen); }
/** * Generate and encapsulate a random session key. * * @param out the output buffer for the encapsulated key. * @param outOff the offset for the output buffer. * @param keyLen the length of the session key. * @return the random session key. */ public CipherParameters encrypt(byte[] out, int outOff, int keyLen) throws IllegalArgumentException { if (!(key instanceof ECPublicKeyParameters)) { throw new IllegalArgumentException("Public key required for encryption"); } BigInteger n = key.getParameters().getN(); BigInteger h = key.getParameters().getH(); // Generate the ephemeral key pair BigInteger r = BigIntegers.createRandomInRange(ONE, n, rnd); ECPoint gTilde = key.getParameters().getG().multiply(r); // Encode the ephemeral public key byte[] C = gTilde.getEncoded(); System.arraycopy(C, 0, out, outOff, C.length); // Compute the static-ephemeral key agreement BigInteger rPrime; if (CofactorMode) { rPrime = r.multiply(h).mod(n); } else { rPrime = r; } ECPoint hTilde = ((ECPublicKeyParameters)key).getQ().multiply(rPrime); // Encode the shared secret value int PEHlen = (key.getParameters().getCurve().getFieldSize() + 7) / 8; byte[] PEH = BigIntegers.asUnsignedByteArray(PEHlen, hTilde.getX().toBigInteger()); // Initialise the KDF byte[] kdfInput; if (SingleHashMode) { kdfInput = new byte[C.length + PEH.length]; System.arraycopy(C, 0, kdfInput, 0, C.length); System.arraycopy(PEH, 0, kdfInput, C.length, PEH.length); } else { kdfInput = PEH; } kdf.init(new KDFParameters(kdfInput, null)); // Generate the secret key byte[] K = new byte[keyLen]; kdf.generateBytes(K, 0, K.length); // Return the ciphertext return new KeyParameter(K); }
/** * Decrypt an encapsulated session key. * * @param in the input buffer for the encapsulated key. * @param inOff the offset for the input buffer. * @param inLen the length of the encapsulated key. * @param keyLen the length of the session key. * @return the session key. */ public CipherParameters decrypt(byte[] in, int inOff, int inLen, int keyLen) throws IllegalArgumentException { if (!(key instanceof ECPrivateKeyParameters)) { throw new IllegalArgumentException("Private key required for encryption"); } BigInteger n = key.getParameters().getN(); BigInteger h = key.getParameters().getH(); // Decode the ephemeral public key byte[] C = new byte[inLen]; System.arraycopy(in, inOff, C, 0, inLen); ECPoint gTilde = key.getParameters().getCurve().decodePoint(C); // Compute the static-ephemeral key agreement ECPoint gHat; if ((CofactorMode) || (OldCofactorMode)) { gHat = gTilde.multiply(h); } else { gHat = gTilde; } BigInteger xHat; if (CofactorMode) { xHat = ((ECPrivateKeyParameters)key).getD().multiply(h.modInverse(n)).mod(n); } else { xHat = ((ECPrivateKeyParameters)key).getD(); } ECPoint hTilde = gHat.multiply(xHat); // Encode the shared secret value int PEHlen = (key.getParameters().getCurve().getFieldSize() + 7) / 8; byte[] PEH = BigIntegers.asUnsignedByteArray(PEHlen, hTilde.getX().toBigInteger()); // Initialise the KDF byte[] kdfInput; if (SingleHashMode) { kdfInput = new byte[C.length + PEH.length]; System.arraycopy(C, 0, kdfInput, 0, C.length); System.arraycopy(PEH, 0, kdfInput, C.length, PEH.length); } else { kdfInput = PEH; } kdf.init(new KDFParameters(kdfInput, null)); // Generate the secret key byte[] K = new byte[keyLen]; kdf.generateBytes(K, 0, K.length); return new KeyParameter(K); }
public byte[] processBlock( byte[] in, int inOff, int inLen) throws InvalidCipherTextException { if (forEncryption) { if (keyPairGenerator != null) { EphemeralKeyPair ephKeyPair = keyPairGenerator.generate(); this.privParam = ephKeyPair.getKeyPair().getPrivate(); this.V = ephKeyPair.getEncodedPublicKey(); } } else { if (keyParser != null) { ByteArrayInputStream bIn = new ByteArrayInputStream(in, inOff, inLen); try { this.pubParam = keyParser.readKey(bIn); } catch (IOException e) { throw new InvalidCipherTextException("unable to recover ephemeral public key: " + e.getMessage(), e); } int encLength = (inLen - bIn.available()); this.V = Arrays.copyOfRange(in, inOff, inOff + encLength); } } // Compute the common value and convert to byte array. agree.init(privParam); BigInteger z = agree.calculateAgreement(pubParam); byte[] Z = BigIntegers.asUnsignedByteArray(agree.getFieldSize(), z); // Create input to KDF. if (V.length != 0) { byte[] VZ = Arrays.concatenate(V, Z); Arrays.fill(Z, (byte)0); Z = VZ; } try { // Initialise the KDF. KDFParameters kdfParam = new KDFParameters(Z, param.getDerivationV()); kdf.init(kdfParam); return forEncryption ? encryptBlock(in, inOff, inLen) : decryptBlock(in, inOff, inLen); } finally { Arrays.fill(Z, (byte)0); } }
/** * Generate and encapsulate a random session key. * * @param out the output buffer for the encapsulated key. * @param outOff the offset for the output buffer. * @param keyLen the length of the session key. * @return the random session key. */ public CipherParameters encrypt(byte[] out, int outOff, int keyLen) throws IllegalArgumentException { if (!(key instanceof ECPublicKeyParameters)) { throw new IllegalArgumentException("Public key required for encryption"); } ECPublicKeyParameters ecPubKey = (ECPublicKeyParameters)key; ECDomainParameters ecParams = ecPubKey.getParameters(); ECCurve curve = ecParams.getCurve(); BigInteger n = ecParams.getN(); BigInteger h = ecParams.getH(); // Generate the ephemeral key pair BigInteger r = BigIntegers.createRandomInRange(ONE, n, rnd); // Compute the static-ephemeral key agreement BigInteger rPrime = CofactorMode ? r.multiply(h).mod(n) : r; ECPoint[] ghTilde = new ECPoint[]{ ecParams.getG().multiply(r), ecPubKey.getQ().multiply(rPrime) }; // NOTE: More efficient than normalizing each individually curve.normalizeAll(ghTilde); ECPoint gTilde = ghTilde[0], hTilde = ghTilde[1]; // Encode the ephemeral public key byte[] C = gTilde.getEncoded(); System.arraycopy(C, 0, out, outOff, C.length); // Encode the shared secret value byte[] PEH = hTilde.getAffineXCoord().getEncoded(); // Initialise the KDF byte[] kdfInput; if (SingleHashMode) { kdfInput = new byte[C.length + PEH.length]; System.arraycopy(C, 0, kdfInput, 0, C.length); System.arraycopy(PEH, 0, kdfInput, C.length, PEH.length); } else { kdfInput = PEH; } kdf.init(new KDFParameters(kdfInput, null)); // Generate the secret key byte[] K = new byte[keyLen]; kdf.generateBytes(K, 0, K.length); // Return the ciphertext return new KeyParameter(K); }
/** * Decrypt an encapsulated session key. * * @param in the input buffer for the encapsulated key. * @param inOff the offset for the input buffer. * @param inLen the length of the encapsulated key. * @param keyLen the length of the session key. * @return the session key. */ public CipherParameters decrypt(byte[] in, int inOff, int inLen, int keyLen) throws IllegalArgumentException { if (!(key instanceof ECPrivateKeyParameters)) { throw new IllegalArgumentException("Private key required for encryption"); } ECPrivateKeyParameters ecPrivKey = (ECPrivateKeyParameters)key; ECDomainParameters ecParams = ecPrivKey.getParameters(); ECCurve curve = ecParams.getCurve(); BigInteger n = ecParams.getN(); BigInteger h = ecParams.getH(); // Decode the ephemeral public key byte[] C = new byte[inLen]; System.arraycopy(in, inOff, C, 0, inLen); // NOTE: Decoded points are already normalized (i.e in affine form) ECPoint gTilde = curve.decodePoint(C); // Compute the static-ephemeral key agreement ECPoint gHat = gTilde; if ((CofactorMode) || (OldCofactorMode)) { gHat = gHat.multiply(h); } BigInteger xHat = ecPrivKey.getD(); if (CofactorMode) { xHat = xHat.multiply(h.modInverse(n)).mod(n); } ECPoint hTilde = gHat.multiply(xHat).normalize(); // Encode the shared secret value byte[] PEH = hTilde.getAffineXCoord().getEncoded(); // Initialise the KDF byte[] kdfInput; if (SingleHashMode) { kdfInput = new byte[C.length + PEH.length]; System.arraycopy(C, 0, kdfInput, 0, C.length); System.arraycopy(PEH, 0, kdfInput, C.length, PEH.length); } else { kdfInput = PEH; } kdf.init(new KDFParameters(kdfInput, null)); // Generate the secret key byte[] K = new byte[keyLen]; kdf.generateBytes(K, 0, K.length); return new KeyParameter(K); }