org.bouncycastle.crypto.test.PKCS5Test Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bouncycastle Show documentation
Show all versions of bouncycastle 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 and up. 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.crypto.test;
import java.io.ByteArrayInputStream;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo;
import org.bouncycastle.asn1.pkcs.EncryptionScheme;
import org.bouncycastle.asn1.pkcs.PBES2Parameters;
import org.bouncycastle.asn1.pkcs.PBKDF2Params;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.RC2CBCParameter;
import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.PBEParametersGenerator;
import org.bouncycastle.crypto.engines.DESEngine;
import org.bouncycastle.crypto.engines.DESedeEngine;
import org.bouncycastle.crypto.engines.RC2Engine;
import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.util.test.SimpleTest;
/**
* A test class for PKCS5 PBES2 with PBKDF2 (PKCS5 v2.0) using
* test vectors provider at
*
* RSA's PKCS5 Page
*
* The vectors are Base 64 encoded and encrypted using the password "password"
* (without quotes). They should all yield the same PrivateKeyInfo object.
*/
public class PKCS5Test
extends SimpleTest
{
/**
* encrypted using des-cbc.
*/
static byte[] sample1 = Base64.decode(
"MIIBozA9BgkqhkiG9w0BBQ0wMDAbBgkqhkiG9w0BBQwwDgQIfWBDXwLp4K4CAggA"
+ "MBEGBSsOAwIHBAiaCF/AvOgQ6QSCAWDWX4BdAzCRNSQSANSuNsT5X8mWYO27mr3Y"
+ "9c9LoBVXGNmYWKA77MI4967f7SmjNcgXj3xNE/jmnVz6hhsjS8E5VPT3kfyVkpdZ"
+ "0lr5e9Yk2m3JWpPU7++v5zBkZmC4V/MwV/XuIs6U+vykgzMgpxQg0oZKS9zgmiZo"
+ "f/4dOCL0UtCDnyOSvqT7mCVIcMDIEKu8QbVlgZYBop08l60EuEU3gARUo8WsYQmO"
+ "Dz/ldx0Z+znIT0SXVuOwc+RVItC5T/Qx+aijmmpt+9l14nmaGBrEkmuhmtdvU/4v"
+ "aptewGRgmjOfD6cqK+zs0O5NrrJ3P/6ZSxXj91CQgrThGfOv72bUncXEMNtc8pks"
+ "2jpHFjGMdKufnadAD7XuMgzkkaklEXZ4f5tU6heIIwr51g0GBEGF96gYPFnjnSQM"
+ "75JE02Clo+DfcfXpcybPTwwFg2jd6JTTOfkdf6OdSlA/1XNK43FA");
/**
* encrypted using des-ede3-cbc.
*/
static byte[] sample2 = Base64.decode(
"MIIBpjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIeFeOWl1jywYCAggA"
+ "MBQGCCqGSIb3DQMHBAjUJ5eGBhQGtQSCAWBrHrRgqO8UUMLcWzZEtpk1l3mjxiF/"
+ "koCMkHsFwowgyWhEbgIkTgbSViK54LVK8PskekcGNLph+rB6bGZ7pPbL5pbXASJ8"
+ "+MkQcG3FZdlS4Ek9tTJDApj3O1UubZGFG4uvTlJJFbF1BOJ3MkY3XQ9Gl1qwv7j5"
+ "6e103Da7Cq9+oIDKmznza78XXQYrUsPo8mJGjUxPskEYlzwvHjKubRnYm/K6RKhi"
+ "5f4zX4BQ/Dt3H812ZjRXrsjAJP0KrD/jyD/jCT7zNBVPH1izBds+RwizyQAHwfNJ"
+ "BFR78TH4cgzB619X47FDVOnT0LqQNVd0O3cSwnPrXE9XR3tPayE+iOB15llFSmi8"
+ "z0ByOXldEpkezCn92Umk++suzIVj1qfsK+bv2phZWJPbLEIWPDRHUbYf76q5ArAr"
+ "u4xtxT/hoK3krEs/IN3d70qjlUJ36SEw1UaZ82PWhakQbdtu39ZraMJB");
/**
* encrypted using rc2-cbc.
*/
static byte[] sample3 = Base64.decode(
"MIIBrjBIBgkqhkiG9w0BBQ0wOzAeBgkqhkiG9w0BBQwwEQQIrHyQPBZqWLUCAggA"
+ "AgEQMBkGCCqGSIb3DQMCMA0CAToECEhbh7YZKiPSBIIBYCT1zp6o5jpFlIkgwPop"
+ "7bW1+8ACr4exqzkeb3WflQ8cWJ4cURxzVdvxUnXeW1VJdaQZtjS/QHs5GhPTG/0f"
+ "wtvnaPfwrIJ3FeGaZfcg2CrYhalOFmEb4xrE4KyoEQmUN8tb/Cg94uzd16BOPw21"
+ "RDnE8bnPdIGY7TyL95kbkqH23mK53pi7h+xWIgduW+atIqDyyt55f7WMZcvDvlj6"
+ "VpN/V0h+qxBHL274WA4dj6GYgeyUFpi60HdGCK7By2TBy8h1ZvKGjmB9h8jZvkx1"
+ "MkbRumXxyFsowTZawyYvO8Um6lbfEDP9zIEUq0IV8RqH2MRyblsPNSikyYhxX/cz"
+ "tdDxRKhilySbSBg5Kr8OfcwKp9bpinN96nmG4xr3Tch1bnVvqJzOQ5+Vva2WwVvH"
+ "2JkWvYm5WaANg4Q6bRxu9vz7DuhbJjQdZbxFezIAgrJdSe92B00jO/0Kny1WjiVO"
+ "6DA=");
static byte[] result = Hex.decode(
"30820155020100300d06092a864886f70d01010105000482013f3082013b020100024100"
+ "debbfc2c09d61bada2a9462f24224e54cc6b3cc0755f15ce318ef57e79df17026b6a85cc"
+ "a12428027245045df2052a329a2f9ad3d17b78a10572ad9b22bf343b020301000102402d"
+ "90a96adcec472743527bc023153d8f0d6e96b40c8ed228276d467d843306429f8670559b"
+ "f376dd41857f6397c2fc8d95e0e53ed62de420b855430ee4a1b8a1022100ffcaf0838239"
+ "31e073ff534f06a5d415b3d414bc614a4544a3dff7ed271817eb022100deea30242117db"
+ "2d3b8837f58f1da530ff83cf9283680da33683ec4e583610f1022100e6026381adb0a683"
+ "f16a8f4c096b462979b9e4277cc89f3ed8a905b46fa9ff9f02210097c146d4d1d2b3dbaf"
+ "53a504ff51674c5c271800de84d003f4f10ac6ab36e38102202bfa141f10bda874e1017d"
+ "845e82767c1c38e82745daf421f0c8cd09d7652387");
private class PBETest
extends SimpleTest
{
int id;
BufferedBlockCipher cipher;
byte[] sample;
int keySize;
PBETest(
int id,
BufferedBlockCipher cipher,
byte[] sample,
int keySize)
{
this.id = id;
this.cipher = cipher;
this.sample = sample;
this.keySize = keySize;
}
public String getName()
{
return cipher.getUnderlyingCipher().getAlgorithmName() + " PKCS5S2 Test " + id;
}
public void performTest()
{
char[] password = { 'p', 'a', 's', 's', 'w', 'o', 'r', 'd' };
PBEParametersGenerator generator = new PKCS5S2ParametersGenerator();
ByteArrayInputStream bIn = new ByteArrayInputStream(sample);
ASN1InputStream dIn = new ASN1InputStream(bIn);
EncryptedPrivateKeyInfo info = null;
try
{
info = EncryptedPrivateKeyInfo.getInstance(dIn.readObject());
}
catch (Exception e)
{
fail("failed construction - exception " + e.toString(), e);
}
PBES2Parameters alg = PBES2Parameters.getInstance(info.getEncryptionAlgorithm().getParameters());
PBKDF2Params func = PBKDF2Params.getInstance(alg.getKeyDerivationFunc().getParameters());
EncryptionScheme scheme = alg.getEncryptionScheme();
if (func.getKeyLength() != null)
{
keySize = func.getKeyLength().intValue() * 8;
}
int iterationCount = func.getIterationCount().intValue();
byte[] salt = func.getSalt();
generator.init(
PBEParametersGenerator.PKCS5PasswordToBytes(password),
salt,
iterationCount);
CipherParameters param;
if (scheme.getAlgorithm().equals(PKCSObjectIdentifiers.RC2_CBC))
{
RC2CBCParameter rc2Params = RC2CBCParameter.getInstance(scheme.getParameters());
byte[] iv = rc2Params.getIV();
param = new ParametersWithIV(generator.generateDerivedParameters(keySize), iv);
}
else
{
byte[] iv = ASN1OctetString.getInstance(scheme.getParameters()).getOctets();
param = new ParametersWithIV(generator.generateDerivedParameters(keySize), iv);
}
cipher.init(false, param);
byte[] data = info.getEncryptedData();
byte[] out = new byte[cipher.getOutputSize(data.length)];
int len = cipher.processBytes(data, 0, data.length, out, 0);
try
{
len += cipher.doFinal(out, len);
}
catch (Exception e)
{
fail("failed doFinal - exception " + e.toString());
}
if (result.length != len)
{
fail("failed length");
}
for (int i = 0; i != len; i++)
{
if (out[i] != result[i])
{
fail("failed comparison");
}
}
}
}
public String getName()
{
return "PKCS5S2";
}
public void performTest()
throws Exception
{
BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new DESEngine()));
SimpleTest test = new PBETest(0, cipher, sample1, 64);
test.performTest();
cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new DESedeEngine()));
test = new PBETest(1, cipher, sample2, 192);
test.performTest();
cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new RC2Engine()));
test = new PBETest(2, cipher, sample3, 0);
test.performTest();
//
// RFC 3211 tests
//
char[] password = { 'p', 'a', 's', 's', 'w', 'o', 'r', 'd' };
PBEParametersGenerator generator = new PKCS5S2ParametersGenerator();
byte[] salt = Hex.decode("1234567878563412");
generator.init(
PBEParametersGenerator.PKCS5PasswordToBytes(password),
salt,
5);
if (!areEqual(((KeyParameter)generator.generateDerivedParameters(64)).getKey(), Hex.decode("d1daa78615f287e6")))
{
fail("64 test failed");
}
password = "All n-entities must communicate with other n-entities via n-1 entiteeheehees".toCharArray();
generator.init(
PBEParametersGenerator.PKCS5PasswordToBytes(password),
salt,
500);
if (!areEqual(((KeyParameter)generator.generateDerivedParameters(192)).getKey(), Hex.decode("6a8970bf68c92caea84a8df28510858607126380cc47ab2d")))
{
fail("192 test failed");
}
generator.init(PBEParametersGenerator.PKCS5PasswordToBytes(password), salt, 60000);
if (!areEqual(((KeyParameter)generator.generateDerivedParameters(192)).getKey(), Hex.decode("29aaef810c12ecd2236bbcfb55407f9852b5573dc1c095bb")))
{
fail("192 (60000) test failed");
}
}
public static void main(
String[] args)
{
runTest(new PKCS5Test());
}
}