Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -32,6 +32,7 @@
import java.security.spec.InvalidParameterSpecException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEParameterSpec;
import sun.security.util.PBKDF2Parameters;
import sun.security.util.*;

/**
Expand Down Expand Up @@ -93,7 +94,7 @@
abstract class PBES2Parameters extends AlgorithmParametersSpi {

private static final ObjectIdentifier pkcs5PBKDF2_OID =
ObjectIdentifier.of(KnownOIDs.PBKDF2WithHmacSHA1);
ObjectIdentifier.of(KnownOIDs.PBKDF2);
private static final ObjectIdentifier pkcs5PBES2_OID =
ObjectIdentifier.of(KnownOIDs.PBES2);
private static final ObjectIdentifier aes128CBC_OID =
Expand Down Expand Up @@ -224,77 +225,32 @@ protected void engineInit(byte[] encoded)
// next DerValue as the real PBES2-params.
if (kdf.getTag() == DerValue.tag_ObjectId) {
pBES2_params = pBES2_params.data.getDerValue();
if (pBES2_params.tag != DerValue.tag_Sequence) {
throw new IOException("PBE parameter parsing error: "
+ "not an ASN.1 SEQUENCE tag");
}
kdf = pBES2_params.data.getDerValue();
}

String kdfAlgo = parseKDF(kdf);

if (pBES2_params.tag != DerValue.tag_Sequence) {
throw new IOException("PBE parameter parsing error: "
+ "not an ASN.1 SEQUENCE tag");
}
String cipherAlgo = parseES(pBES2_params.data.getDerValue());

this.pbes2AlgorithmName = "PBEWith" + kdfAlgo + "And" + cipherAlgo;
}

private String parseKDF(DerValue keyDerivationFunc) throws IOException {

if (!pkcs5PBKDF2_OID.equals(keyDerivationFunc.data.getOID())) {
if (!pkcs5PBKDF2_OID.equals(kdf.data.getOID())) {
throw new IOException("PBE parameter parsing error: "
+ "expecting the object identifier for PBKDF2");
}
if (keyDerivationFunc.tag != DerValue.tag_Sequence) {
if (kdf.tag != DerValue.tag_Sequence) {
throw new IOException("PBE parameter parsing error: "
+ "not an ASN.1 SEQUENCE tag");
}
DerValue pBKDF2_params = keyDerivationFunc.data.getDerValue();
if (pBKDF2_params.tag != DerValue.tag_Sequence) {
throw new IOException("PBE parameter parsing error: "
+ "not an ASN.1 SEQUENCE tag");
}
DerValue specified = pBKDF2_params.data.getDerValue();
// the 'specified' ASN.1 CHOICE for 'salt' is supported
if (specified.tag == DerValue.tag_OctetString) {
salt = specified.getOctetString();
} else {
// the 'otherSource' ASN.1 CHOICE for 'salt' is not supported
throw new IOException("PBE parameter parsing error: "
+ "not an ASN.1 OCTET STRING tag");
}
iCount = pBKDF2_params.data.getInteger();
DerValue pBKDF2_params = kdf.data.getDerValue();

// keyLength INTEGER (1..MAX) OPTIONAL,
var ksDer = pBKDF2_params.data.getOptional(DerValue.tag_Integer);
if (ksDer.isPresent()) {
keysize = ksDer.get().getInteger() * 8; // keysize (in bits)
}
var kdfParams = new PBKDF2Parameters(pBKDF2_params);
String kdfAlgo = kdfParams.getPrfAlgo();
salt = kdfParams.getSalt();
iCount = kdfParams.getIterationCount();
keysize = kdfParams.getKeyLength();

// prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1
String kdfAlgo;
var prfDer = pBKDF2_params.data.getOptional(DerValue.tag_Sequence);
if (prfDer.isPresent()) {
DerValue prf = prfDer.get();
kdfAlgo_OID = prf.data.getOID();
KnownOIDs o = KnownOIDs.findMatch(kdfAlgo_OID.toString());
if (o == null || (!o.stdName().equals("HmacSHA1") &&
!o.stdName().equals("HmacSHA224") &&
!o.stdName().equals("HmacSHA256") &&
!o.stdName().equals("HmacSHA384") &&
!o.stdName().equals("HmacSHA512") &&
!o.stdName().equals("HmacSHA512/224") &&
!o.stdName().equals("HmacSHA512/256"))) {
throw new IOException("PBE parameter parsing error: "
+ "expecting the object identifier for a HmacSHA key "
+ "derivation function");
}
kdfAlgo = o.stdName();
prf.data.getOptional(DerValue.tag_Null);
prf.data.atEnd();
} else {
kdfAlgo = "HmacSHA1";
}
return kdfAlgo;
String cipherAlgo = parseES(pBES2_params.data.getDerValue());

this.pbes2AlgorithmName = "PBEWith" + kdfAlgo + "And" + cipherAlgo;
}

private String parseES(DerValue encryptionScheme) throws IOException {
Expand Down Expand Up @@ -345,26 +301,9 @@ protected byte[] engineGetEncoded() throws IOException {

DerOutputStream pBES2_params = new DerOutputStream();

DerOutputStream keyDerivationFunc = new DerOutputStream();
keyDerivationFunc.putOID(pkcs5PBKDF2_OID);

DerOutputStream pBKDF2_params = new DerOutputStream();
pBKDF2_params.putOctetString(salt); // choice: 'specified OCTET STRING'
pBKDF2_params.putInteger(iCount);

if (keysize > 0) {
pBKDF2_params.putInteger(keysize / 8); // derived key length (in octets)
}

DerOutputStream prf = new DerOutputStream();
// algorithm is id-hmacWith<MD>
prf.putOID(kdfAlgo_OID);
// parameters is 'NULL'
prf.putNull();
pBKDF2_params.write(DerValue.tag_Sequence, prf);

keyDerivationFunc.write(DerValue.tag_Sequence, pBKDF2_params);
pBES2_params.write(DerValue.tag_Sequence, keyDerivationFunc);
// keysize encoded as octets
pBES2_params.writeBytes(PBKDF2Parameters.encode(salt, iCount,
keysize/8, kdfAlgo_OID));

DerOutputStream encryptionScheme = new DerOutputStream();
// algorithm is id-aes128-CBC or id-aes256-CBC
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
* @author Valerie Peng
*
*/
final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
public final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {

@java.io.Serial
private static final long serialVersionUID = -2234868909660948157L;
Expand Down
Loading