com.google.crypto.tink.subtle.EciesAeadHkdfHybridDecrypt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tink-android Show documentation
Show all versions of tink-android Show documentation
Tink is a small cryptographic library that provides a safe, simple, agile and fast way to accomplish some common cryptographic tasks.
The newest version!
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package com.google.crypto.tink.subtle;
import static com.google.crypto.tink.internal.Util.isPrefix;
import com.google.crypto.tink.AccessesPartialKey;
import com.google.crypto.tink.HybridDecrypt;
import com.google.crypto.tink.InsecureSecretKeyAccess;
import com.google.crypto.tink.hybrid.EciesPrivateKey;
import com.google.crypto.tink.hybrid.internal.EciesDemHelper;
import com.google.crypto.tink.internal.BigIntegerEncoding;
import java.security.GeneralSecurityException;
import java.security.interfaces.ECPrivateKey;
import java.security.spec.EllipticCurve;
import java.util.Arrays;
/**
* ECIES encryption with HKDF-KEM (key encapsulation mechanism) and AEAD-DEM (data encapsulation
* mechanism).
*
* @since 1.0.0
*/
public final class EciesAeadHkdfHybridDecrypt implements HybridDecrypt {
private final ECPrivateKey recipientPrivateKey;
private final EciesHkdfRecipientKem recipientKem;
private final String hkdfHmacAlgo;
private final byte[] hkdfSalt;
private final EllipticCurves.PointFormatType ecPointFormat;
private final EciesDemHelper.Dem dem;
private final byte[] outputPrefix;
private EciesAeadHkdfHybridDecrypt(
final ECPrivateKey recipientPrivateKey,
final byte[] hkdfSalt,
String hkdfHmacAlgo,
EllipticCurves.PointFormatType ecPointFormat,
EciesDemHelper.Dem dem,
byte[] outputPrefix) {
this.recipientPrivateKey = recipientPrivateKey;
this.recipientKem = new EciesHkdfRecipientKem(recipientPrivateKey);
this.hkdfSalt = hkdfSalt;
this.hkdfHmacAlgo = hkdfHmacAlgo;
this.ecPointFormat = ecPointFormat;
this.dem = dem;
this.outputPrefix = outputPrefix;
}
@AccessesPartialKey
public static HybridDecrypt create(EciesPrivateKey key) throws GeneralSecurityException {
EllipticCurves.CurveType curveType =
EciesAeadHkdfHybridEncrypt.CURVE_TYPE_CONVERTER.toProtoEnum(
key.getParameters().getCurveType());
ECPrivateKey recipientPrivateKey =
EllipticCurves.getEcPrivateKey(
curveType,
BigIntegerEncoding.toBigEndianBytes(
key.getNistPrivateKeyValue().getBigInteger(InsecureSecretKeyAccess.get())));
byte[] hkdfSalt = new byte[0];
if (key.getParameters().getSalt() != null) {
hkdfSalt = key.getParameters().getSalt().toByteArray();
}
return new EciesAeadHkdfHybridDecrypt(
recipientPrivateKey,
hkdfSalt,
EciesAeadHkdfHybridEncrypt.toHmacAlgo(key.getParameters().getHashType()),
EciesAeadHkdfHybridEncrypt.POINT_FORMAT_TYPE_CONVERTER.toProtoEnum(
key.getParameters().getNistCurvePointFormat()),
EciesDemHelper.getDem(key.getParameters()),
key.getOutputPrefix().toByteArray());
}
@Override
public byte[] decrypt(final byte[] ciphertext, final byte[] contextInfo)
throws GeneralSecurityException {
if (!isPrefix(outputPrefix, ciphertext)) {
throw new GeneralSecurityException("Invalid ciphertext (output prefix mismatch)");
}
int prefixSize = outputPrefix.length;
EllipticCurve curve = recipientPrivateKey.getParams().getCurve();
int headerSize = EllipticCurves.encodingSizeInBytes(curve, ecPointFormat);
if (ciphertext.length < prefixSize + headerSize) {
throw new GeneralSecurityException("ciphertext too short");
}
byte[] kemBytes = Arrays.copyOfRange(ciphertext, prefixSize, prefixSize + headerSize);
byte[] symmetricKey =
recipientKem.generateKey(
kemBytes,
hkdfHmacAlgo,
hkdfSalt,
contextInfo,
dem.getSymmetricKeySizeInBytes(),
ecPointFormat);
return dem.decrypt(symmetricKey, ciphertext, prefixSize + headerSize);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy