All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bouncycastle.openpgp.operator.RFC6637KDFCalculator Maven / Gradle / Ivy

Go to download

The Bouncy Castle Java API for handling the OpenPGP protocol. This jar contains the OpenPGP API for JDK 1.5 to JDK 1.7. The APIs can be used in conjunction with a JCE/JCA provider such as the one provided with the Bouncy Castle Cryptography APIs.

There is a newer version: 1.70
Show newest version
package org.bouncycastle.openpgp.operator;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.bcpg.PublicKeyAlgorithmTags;
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.util.encoders.Hex;

/**
 * Calculator for the EC based KDF algorithm described in RFC 6637
 * @deprecated this class is no longer required and will be removed.
 */
public class RFC6637KDFCalculator
{
    // "Anonymous Sender    ", which is the octet sequence
    private static final byte[] ANONYMOUS_SENDER = Hex.decode("416E6F6E796D6F75732053656E64657220202020");

    private final PGPDigestCalculator digCalc;
    private final int keyAlgorithm;

    public RFC6637KDFCalculator(PGPDigestCalculator digCalc, int keyAlgorithm)
    {
        this.digCalc = digCalc;
        this.keyAlgorithm = keyAlgorithm;
    }

    public byte[] createKey(ASN1ObjectIdentifier curveOID,  ECPoint s, byte[] recipientFingerPrint)
        throws PGPException
    {
        try
        {
            // RFC 6637 - Section 8
            // curve_OID_len = (byte)len(curve_OID);
            // Param = curve_OID_len || curve_OID || public_key_alg_ID || 03
            // || 01 || KDF_hash_ID || KEK_alg_ID for AESKeyWrap || "Anonymous
            // Sender    " || recipient_fingerprint;
            // Z_len = the key size for the KEK_alg_ID used with AESKeyWrap
            // Compute Z = KDF( S, Z_len, Param );
            ByteArrayOutputStream pOut = new ByteArrayOutputStream();

            byte[] encOid = curveOID.getEncoded();

            pOut.write(encOid, 1, encOid.length - 1);
            pOut.write(PublicKeyAlgorithmTags.ECDH);
            pOut.write(0x03);
            pOut.write(0x01);
            pOut.write(digCalc.getAlgorithm());
            pOut.write(keyAlgorithm);
            pOut.write(ANONYMOUS_SENDER);
            pOut.write(recipientFingerPrint);

            return KDF(digCalc, s, getKeyLen(keyAlgorithm), pOut.toByteArray());
        }
        catch (IOException e)
        {
            throw new PGPException("Exception performing KDF: " + e.getMessage(), e);
        }
    }

    // RFC 6637 - Section 7
    //   Implements KDF( X, oBits, Param );
    //   Input: point X = (x,y)
    //   oBits - the desired size of output
    //   hBits - the size of output of hash function Hash
    //   Param - octets representing the parameters
    //   Assumes that oBits <= hBits
    //   Convert the point X to the octet string, see section 6:
    //   ZB' = 04 || x || y
    //   and extract the x portion from ZB'
    //         ZB = x;
    //         MB = Hash ( 00 || 00 || 00 || 01 || ZB || Param );
    //   return oBits leftmost bits of MB.
    private static byte[] KDF(PGPDigestCalculator digCalc, ECPoint s, int keyLen, byte[] param)
        throws IOException
    {
        byte[] ZB = s.getXCoord().getEncoded();

        OutputStream dOut = digCalc.getOutputStream();

        dOut.write(0x00);
        dOut.write(0x00);
        dOut.write(0x00);
        dOut.write(0x01);
        dOut.write(ZB);
        dOut.write(param);

        byte[] digest = digCalc.getDigest();

        byte[] key = new byte[keyLen];

        System.arraycopy(digest, 0, key, 0, key.length);

        return key;
    }

    private static int getKeyLen(int algID)
        throws PGPException
    {
        switch (algID)
        {
        case SymmetricKeyAlgorithmTags.AES_128:
            return 16;
        case SymmetricKeyAlgorithmTags.AES_192:
            return 24;
        case SymmetricKeyAlgorithmTags.AES_256:
            return 32;
        default:
            throw new PGPException("unknown symmetric algorithm ID: " + algID);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy