org.bouncycastle.its.jcajce.JceETSIKeyWrapper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bcpkix-jdk15to18 Show documentation
Show all versions of bcpkix-jdk15to18 Show documentation
The Bouncy Castle Java APIs for CMS, PKCS, EAC, TSP, CMP, CRMF, OCSP, and certificate generation. This jar contains APIs for JDK 1.5 to JDK 1.8. The APIs can be used in conjunction with a JCE/JCA provider such as the one provided with the Bouncy Castle Cryptography APIs.
package org.bouncycastle.its.jcajce;
import java.security.Provider;
import java.security.interfaces.ECPublicKey;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.sec.SECObjectIdentifiers;
import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.its.ETSIKeyWrapper;
import org.bouncycastle.jcajce.spec.IESKEMParameterSpec;
import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
import org.bouncycastle.jcajce.util.JcaJceHelper;
import org.bouncycastle.jcajce.util.NamedJcaJceHelper;
import org.bouncycastle.jcajce.util.ProviderJcaJceHelper;
import org.bouncycastle.oer.its.ieee1609dot2.EncryptedDataEncryptionKey;
import org.bouncycastle.oer.its.ieee1609dot2.basetypes.EccP256CurvePoint;
import org.bouncycastle.oer.its.ieee1609dot2.basetypes.EciesP256EncryptedKey;
import org.bouncycastle.util.Arrays;
public class JceETSIKeyWrapper
implements ETSIKeyWrapper
{
private final ECPublicKey recipientKey;
private final byte[] recipientHash;
private final JcaJceHelper helper;
private JceETSIKeyWrapper(ECPublicKey key, byte[] recipientHash, JcaJceHelper helper)
{
this.recipientKey = key;
this.recipientHash = recipientHash;
this.helper = helper;
}
public EncryptedDataEncryptionKey wrap(byte[] secretKey)
{
try
{
Cipher etsiKem = helper.createCipher("ETSIKEMwithSHA256");
etsiKem.init(Cipher.WRAP_MODE, recipientKey, new IESKEMParameterSpec(recipientHash, true));
byte[] wrappedKey = etsiKem.wrap(new SecretKeySpec(secretKey, "AES"));
int size = (recipientKey.getParams().getCurve().getField().getFieldSize() + 7) / 8;
if (wrappedKey[0] == 0x04)
{
size = 2 * size + 1;
}
else
{
size = size + 1;
}
SubjectPublicKeyInfo pkInfo = SubjectPublicKeyInfo.getInstance(recipientKey.getEncoded());
ASN1ObjectIdentifier curveID = ASN1ObjectIdentifier.getInstance(pkInfo.getAlgorithm().getParameters());
EciesP256EncryptedKey key = EciesP256EncryptedKey.builder()
.setV(EccP256CurvePoint.createEncodedPoint(Arrays.copyOfRange(wrappedKey, 0, size)))
.setC(Arrays.copyOfRange(wrappedKey, size, size + secretKey.length))
.setT(Arrays.copyOfRange(wrappedKey, size + secretKey.length, wrappedKey.length))
.createEciesP256EncryptedKey();
if (curveID.equals(SECObjectIdentifiers.secp256r1))
{
return EncryptedDataEncryptionKey.eciesNistP256(key);
}
else if (curveID.equals(TeleTrusTObjectIdentifiers.brainpoolP256r1))
{
return EncryptedDataEncryptionKey.eciesBrainpoolP256r1(key);
}
else
{
throw new IllegalStateException("recipient key curve is not P-256 or Brainpool P256r1");
}
}
catch (Exception ex)
{
throw new RuntimeException(ex.getMessage(), ex);
}
}
public static class Builder
{
private final ECPublicKey recipientKey;
private final byte[] recipientHash;
private JcaJceHelper helper = new DefaultJcaJceHelper();
public Builder(ECPublicKey recipientKey, byte[] recipientHash)
{
this.recipientKey = recipientKey;
this.recipientHash = recipientHash;
}
/**
* Sets the JCE provider to source cryptographic primitives from.
*
* @param provider the JCE provider to use.
* @return the current builder.
*/
public Builder setProvider(Provider provider)
{
this.helper = new ProviderJcaJceHelper(provider);
return this;
}
/**
* Sets the JCE provider to source cryptographic primitives from.
*
* @param providerName the name of the JCE provider to use.
* @return the current builder.
*/
public Builder setProvider(String providerName)
{
this.helper = new NamedJcaJceHelper(providerName);
return this;
}
public JceETSIKeyWrapper build()
{
return new JceETSIKeyWrapper(recipientKey, recipientHash, helper);
}
}
}