Example usage for org.bouncycastle.jcajce.provider.asymmetric.ec BCECPrivateKey getParams

List of usage examples for org.bouncycastle.jcajce.provider.asymmetric.ec BCECPrivateKey getParams

Introduction

In this page you can find the example usage for org.bouncycastle.jcajce.provider.asymmetric.ec BCECPrivateKey getParams.

Prototype

public ECParameterSpec getParams() 

Source Link

Usage

From source file:me.grapebaba.hyperledger.fabric.Crypto.java

License:Apache License

public ByteString eciesDecrypt(PrivateKey recipientPrivateKey, ByteString cipherText) {
    BCECPrivateKey bcecPrivateKey = (BCECPrivateKey) recipientPrivateKey;
    ECNamedCurveSpec ecNamedCurveSpec = (ECNamedCurveSpec) bcecPrivateKey.getParams();
    int level = SecurityLevel.from(ecNamedCurveSpec.getName()).size();

    //cipherText = ephemeralPubKeyBytes + encryptedTokBytes + macBytes
    //ephemeralPubKeyBytes = first ((384+7)/8)*2 + 1 bytes = first 97 bytes
    //hmac is sha3_384 = 48 bytes or sha3_256 = 32 bytes
    int ephemeralPubKeyLength = ((level + 7) / 8) * 2 + 1;
    int hmacLength = level >> 3;
    int cipherTextLength = cipherText.size();

    if (cipherTextLength <= ephemeralPubKeyLength + hmacLength)
        throw new RuntimeException(String.format("Illegal cipherText length: %d must be > %d", cipherTextLength,
                ephemeralPubKeyLength + hmacLength));

    ByteString ephemeralPubKey = cipherText.substring(0, ephemeralPubKeyLength);
    ByteString encryptedContent = cipherText.substring(ephemeralPubKeyLength, cipherTextLength - hmacLength);
    ByteString hmac = cipherText.substring(cipherTextLength - hmacLength);

    ECPrivateKeyParameters ecdhPrivateKeyParameters;
    try {/* w w  w  .  j av a2 s.c  o  m*/
        ecdhPrivateKeyParameters = (ECPrivateKeyParameters) (PrivateKeyFactory
                .createKey(bcecPrivateKey.getEncoded()));
    } catch (IOException e) {
        logger.error("ECIES decrypt load private key exception", e);
        throw new RuntimeException(e);
    }
    ECDomainParameters ecDomainParameters = ecdhPrivateKeyParameters.getParameters();
    ECCurve ecCurve = ecDomainParameters.getCurve();
    ECPublicKeyParameters ecPublicKeyParameters = new ECPublicKeyParameters(
            ecCurve.decodePoint(ephemeralPubKey.toByteArray()), ecDomainParameters);
    BasicAgreement agree = new ECDHBasicAgreement();
    agree.init(ecdhPrivateKeyParameters);
    byte[] keyAgreement = agree.calculateAgreement(ecPublicKeyParameters).toByteArray();

    HKDFParameters hkdfParameters = new HKDFParameters(keyAgreement, null, null);
    HKDFBytesGenerator hkdfBytesGenerator = new HKDFBytesGenerator(digest);
    hkdfBytesGenerator.init(hkdfParameters);
    byte[] hkdfOutputBytes = new byte[AESKEY_LENGTH + HMACKEY_LENGTH];
    hkdfBytesGenerator.generateBytes(hkdfOutputBytes, 0, AESKEY_LENGTH + HMACKEY_LENGTH);
    ByteString hkdfOutput = ByteString.copyFrom(hkdfOutputBytes);
    ByteString aesKey = hkdfOutput.substring(0, AESKEY_LENGTH);
    ByteString hmacKey = hkdfOutput.substring(AESKEY_LENGTH, AESKEY_LENGTH + HMACKEY_LENGTH);
    HMac hMac = new HMac(digest);
    hMac.init(new KeyParameter(hmacKey.toByteArray()));
    hMac.update(encryptedContent.toByteArray(), 0, encryptedContent.size());
    byte[] recoveredHmac = new byte[hMac.getMacSize()];
    hMac.doFinal(recoveredHmac, 0);
    if (!MessageDigest.isEqual(hmac.toByteArray(), recoveredHmac)) {
        throw new RuntimeException("HMAC verify failed");
    }

    CFBBlockCipher aesCipher = new CFBBlockCipher(new AESEngine(), BLOCK_BIT_SIZE);
    ByteString iv = encryptedContent.substring(0, IV_LENGTH);
    CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(aesKey.toByteArray()), iv.toByteArray());
    aesCipher.init(false, ivAndKey);
    byte[] decryptedBytes = new byte[500];
    aesCipher.decryptBlock(encryptedContent.substring(IV_LENGTH).toByteArray(), 0, decryptedBytes, 0);
    return ByteString.copyFrom(decryptedBytes);
}