You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PKCS #12 generating with 600k iterations with code below (similar to openSSLLike example) takes 49-60s (tested in Firefox 115.9.1esr 64bit and Chromium 90 64-bit). Tested that most of the execution time is eaten by last makeInternalValues call (integrity protection envelope).
PKCS #12 generating with 600k iterations on same machine with openssl 3 from Debian 12 takes less than 1s:
$ time openssl pkcs12 -export -in test.crt -inkey test.key -out test.p12 -name 'test' -password pass:1234 -iter 600000
real 0m0.917s
user 0m0.894s
sys 0m0.000s
Is it expected or PKI.js bug?
PKCS #12 generation function code using PKI.js (PBKDF2_ITERATION_COUNT is set to 600000 during test):
// downloadPKCS12 downloads given private key and certificate in encrypted PKCS #12 file.
export async function downloadPKCS12(
keyPair: CryptoKeyPair,
certificate: Certificate,
ownerId: string,
password: string,
filename: string
) {
if (!password) {
throw new Error('password cannot be empty');
}
if (!ownerId) {
throw new Error('ownerId cannot be empty');
}
if (!filename) {
throw new Error('filename cannot be empty');
}
const crypto = getCrypto(true);
const passwordConverted = Convert.FromUtf8String(password);
const certFingerprint = await crypto.digest('SHA-1', certificate.toSchema().toBER(false));
const privateKeyBinary = await crypto.subtle.exportKey('pkcs8', keyPair.privateKey);
const pkcs8Simpl = new PrivateKeyInfo({ schema: fromBER(privateKeyBinary).result });
// Put initial values for PKCS#12 structures.
const pkcs12 = new PFX({
parsedValue: {
integrityMode: 0, // Password-Based Integrity Mode.
authenticatedSafe: new AuthenticatedSafe({
parsedValue: {
safeContents: [
{
privacyMode: 1, // Password-Based Privacy Protection Mode.
value: new SafeContents({
safeBags: [
new SafeBag({
bagId: '1.2.840.113549.1.12.10.1.3',
bagValue: new CertBag({
parsedValue: certificate
}),
bagAttributes: [
new Attribute({
type: '1.2.840.113549.1.9.21', // localKeyID
values: [new OctetString({ valueHex: certFingerprint })]
}),
new Attribute({
type: '1.2.840.113549.1.9.20', // friendlyName
values: [new BmpString({ value: ownerId })]
})
]
})
]
})
},
{
privacyMode: 0, // No-privacy Protection Mode.
value: new SafeContents({
safeBags: [
new SafeBag({
bagId: '1.2.840.113549.1.12.10.1.2',
bagValue: new PKCS8ShroudedKeyBag({
parsedValue: pkcs8Simpl
}),
bagAttributes: [
new Attribute({
type: '1.2.840.113549.1.9.21', // localKeyID
values: [new OctetString({ valueHex: certFingerprint })]
}),
new Attribute({
type: '1.2.840.113549.1.9.20', // friendlyName
values: [new BmpString({ value: ownerId })]
})
]
})
]
})
}
]
}
})
}
});
// Encode internal values for PKCS8ShroudedKeyBag.
if (!(pkcs12.parsedValue && pkcs12.parsedValue.authenticatedSafe)) {
throw new Error('pkcs12.parsedValue.authenticatedSafe is empty');
}
await pkcs12.parsedValue.authenticatedSafe.parsedValue.safeContents[1].value.safeBags[0].bagValue.makeInternalValues(
{
password: passwordConverted,
contentEncryptionAlgorithm: {
name: 'AES-CBC', // OpenSSL can handle AES-CBC only.
length: 256
},
hmacHashAlgorithm: 'SHA-256',
iterationCount: PBKDF2_ITERATION_COUNT
}
);
// Encode internal values for all SafeContents first (create all Privacy Protection envelopes).
await pkcs12.parsedValue.authenticatedSafe.makeInternalValues({
safeContents: [
{
password: passwordConverted,
contentEncryptionAlgorithm: {
name: 'AES-CBC', // OpenSSL can handle AES-CBC only.
length: 256
},
hmacHashAlgorithm: 'SHA-256',
iterationCount: PBKDF2_ITERATION_COUNT
},
{
// Empty parameters for second SafeContent since No Privacy protection mode there.
}
]
});
// Encode internal values for Integrity Protection envelope.
await pkcs12.makeInternalValues({
password: passwordConverted,
iterations: PBKDF2_ITERATION_COUNT, // Big value here causes long generation time.
pbkdf2HashAlgorithm: 'SHA-256', // Least two parameters are equal because at the moment it is not clear how to use PBMAC1 schema with PKCS#12 integrity protection.
hmacHashAlgorithm: 'SHA-256'
});
// Download prepared PKCS #12 content to file.
downloadFile(filename, 'application/pkcs12', pkcs12.toSchema().toBER(false));
}
The text was updated successfully, but these errors were encountered:
PKCS #12 generating with 600k iterations with code below (similar to
openSSLLike example
) takes 49-60s (tested in Firefox 115.9.1esr 64bit and Chromium 90 64-bit). Tested that most of the execution time is eaten by lastmakeInternalValues
call (integrity protection envelope).PKCS #12 generating with 600k iterations on same machine with openssl 3 from Debian 12 takes less than 1s:
Is it expected or PKI.js bug?
PKCS #12 generation function code using PKI.js (
PBKDF2_ITERATION_COUNT
is set to600000
during test):The text was updated successfully, but these errors were encountered: