You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
4.3 KiB
163 lines
4.3 KiB
2 months ago
|
using System;
|
||
|
|
||
|
using Org.BouncyCastle.Crypto;
|
||
|
using Org.BouncyCastle.Crypto.Digests;
|
||
|
using Org.BouncyCastle.Crypto.Parameters;
|
||
|
using Org.BouncyCastle.Math;
|
||
|
using Org.BouncyCastle.Security;
|
||
|
|
||
|
namespace Org.BouncyCastle.Crypto.Generators
|
||
|
{
|
||
|
/**
|
||
|
* Generator for Pbe derived keys and ivs as defined by Pkcs 5 V2.0 Scheme 1.
|
||
|
* Note this generator is limited to the size of the hash produced by the
|
||
|
* digest used to drive it.
|
||
|
* <p>
|
||
|
* The document this implementation is based on can be found at
|
||
|
* <a href="http://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html">
|
||
|
* RSA's Pkcs5 Page</a>
|
||
|
* </p>
|
||
|
*/
|
||
|
public class Pkcs5S1ParametersGenerator
|
||
|
: PbeParametersGenerator
|
||
|
{
|
||
|
private readonly IDigest digest;
|
||
|
|
||
|
/**
|
||
|
* Construct a Pkcs 5 Scheme 1 Parameters generator.
|
||
|
*
|
||
|
* @param digest the digest to be used as the source of derived keys.
|
||
|
*/
|
||
|
public Pkcs5S1ParametersGenerator(
|
||
|
IDigest digest)
|
||
|
{
|
||
|
this.digest = digest;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* the derived key function, the ith hash of the mPassword and the mSalt.
|
||
|
*/
|
||
|
private byte[] GenerateDerivedKey()
|
||
|
{
|
||
|
byte[] digestBytes = new byte[digest.GetDigestSize()];
|
||
|
|
||
|
digest.BlockUpdate(mPassword, 0, mPassword.Length);
|
||
|
digest.BlockUpdate(mSalt, 0, mSalt.Length);
|
||
|
|
||
|
digest.DoFinal(digestBytes, 0);
|
||
|
for (int i = 1; i < mIterationCount; i++)
|
||
|
{
|
||
|
digest.BlockUpdate(digestBytes, 0, digestBytes.Length);
|
||
|
digest.DoFinal(digestBytes, 0);
|
||
|
}
|
||
|
|
||
|
return digestBytes;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Generate a key parameter derived from the mPassword, mSalt, and iteration
|
||
|
* count we are currently initialised with.
|
||
|
*
|
||
|
* @param keySize the size of the key we want (in bits)
|
||
|
* @return a KeyParameter object.
|
||
|
* @exception ArgumentException if the key length larger than the base hash size.
|
||
|
*/
|
||
|
[Obsolete]
|
||
|
public override ICipherParameters GenerateDerivedParameters(
|
||
|
int keySize)
|
||
|
{
|
||
|
return GenerateDerivedMacParameters(keySize);
|
||
|
}
|
||
|
|
||
|
public override ICipherParameters GenerateDerivedParameters(
|
||
|
string algorithm,
|
||
|
int keySize)
|
||
|
{
|
||
|
keySize /= 8;
|
||
|
|
||
|
if (keySize > digest.GetDigestSize())
|
||
|
{
|
||
|
throw new ArgumentException(
|
||
|
"Can't Generate a derived key " + keySize + " bytes long.");
|
||
|
}
|
||
|
|
||
|
byte[] dKey = GenerateDerivedKey();
|
||
|
|
||
|
return ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Generate a key with initialisation vector parameter derived from
|
||
|
* the mPassword, mSalt, and iteration count we are currently initialised
|
||
|
* with.
|
||
|
*
|
||
|
* @param keySize the size of the key we want (in bits)
|
||
|
* @param ivSize the size of the iv we want (in bits)
|
||
|
* @return a ParametersWithIV object.
|
||
|
* @exception ArgumentException if keySize + ivSize is larger than the base hash size.
|
||
|
*/
|
||
|
[Obsolete]
|
||
|
public override ICipherParameters GenerateDerivedParameters(
|
||
|
int keySize,
|
||
|
int ivSize)
|
||
|
{
|
||
|
keySize /= 8;
|
||
|
ivSize /= 8;
|
||
|
|
||
|
if ((keySize + ivSize) > digest.GetDigestSize())
|
||
|
{
|
||
|
throw new ArgumentException(
|
||
|
"Can't Generate a derived key " + (keySize + ivSize) + " bytes long.");
|
||
|
}
|
||
|
|
||
|
byte[] dKey = GenerateDerivedKey();
|
||
|
|
||
|
return new ParametersWithIV(new KeyParameter(dKey, 0, keySize), dKey, keySize, ivSize);
|
||
|
}
|
||
|
|
||
|
public override ICipherParameters GenerateDerivedParameters(
|
||
|
string algorithm,
|
||
|
int keySize,
|
||
|
int ivSize)
|
||
|
{
|
||
|
keySize /= 8;
|
||
|
ivSize /= 8;
|
||
|
|
||
|
if ((keySize + ivSize) > digest.GetDigestSize())
|
||
|
{
|
||
|
throw new ArgumentException(
|
||
|
"Can't Generate a derived key " + (keySize + ivSize) + " bytes long.");
|
||
|
}
|
||
|
|
||
|
byte[] dKey = GenerateDerivedKey();
|
||
|
KeyParameter key = ParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize);
|
||
|
|
||
|
return new ParametersWithIV(key, dKey, keySize, ivSize);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Generate a key parameter for use with a MAC derived from the mPassword,
|
||
|
* mSalt, and iteration count we are currently initialised with.
|
||
|
*
|
||
|
* @param keySize the size of the key we want (in bits)
|
||
|
* @return a KeyParameter object.
|
||
|
* @exception ArgumentException if the key length larger than the base hash size.
|
||
|
*/
|
||
|
public override ICipherParameters GenerateDerivedMacParameters(
|
||
|
int keySize)
|
||
|
{
|
||
|
keySize /= 8;
|
||
|
|
||
|
if (keySize > digest.GetDigestSize())
|
||
|
{
|
||
|
throw new ArgumentException(
|
||
|
"Can't Generate a derived key " + keySize + " bytes long.");
|
||
|
}
|
||
|
|
||
|
byte[] dKey = GenerateDerivedKey();
|
||
|
|
||
|
return new KeyParameter(dKey, 0, keySize);
|
||
|
}
|
||
|
}
|
||
|
}
|