Initial Commit

This commit is contained in:
2023-06-21 12:46:23 -04:00
commit c70248a520
1352 changed files with 336780 additions and 0 deletions

View File

@@ -0,0 +1,99 @@
using System.Collections;
using System.Globalization;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Agreement;
using Org.BouncyCastle.Crypto.Agreement.Kdf;
using Org.BouncyCastle.Crypto.Digests;
namespace Org.BouncyCastle.Security
{
/// <remarks>
/// Utility class for creating IBasicAgreement objects from their names/Oids
/// </remarks>
public sealed class AgreementUtilities
{
private AgreementUtilities()
{
}
private static readonly Hashtable algorithms = new Hashtable();
// private static readonly Hashtable oids = new Hashtable();
static AgreementUtilities()
{
//algorithms[X9ObjectIdentifiers.DHSinglePassCofactorDHSha1KdfScheme.Id] = ?;
algorithms[X9ObjectIdentifiers.DHSinglePassStdDHSha1KdfScheme.Id] = "DHWITHSHA1KDF";
//algorithms[X9ObjectIdentifiers.MqvSinglePassSha1KdfScheme.Id] = ?;
}
public static IBasicAgreement GetBasicAgreement(
DerObjectIdentifier oid)
{
return GetBasicAgreement(oid.Id);
}
public static IBasicAgreement GetBasicAgreement(
string algorithm)
{
string upper = algorithm.ToUpper(CultureInfo.InvariantCulture);
string mechanism = (string) algorithms[upper];
if (mechanism == null)
{
mechanism = upper;
}
switch (mechanism)
{
case "DH":
return new DHBasicAgreement();
case "ECDH":
return new ECDHBasicAgreement();
case "ECDHC":
return new ECDHCBasicAgreement();
}
throw new SecurityUtilityException("Basic Agreement " + algorithm + " not recognised.");
}
public static IBasicAgreement GetBasicAgreementWithKdf(
DerObjectIdentifier oid,
string wrapAlgorithm)
{
return GetBasicAgreementWithKdf(oid.Id, wrapAlgorithm);
}
public static IBasicAgreement GetBasicAgreementWithKdf(
string agreeAlgorithm,
string wrapAlgorithm)
{
string upper = agreeAlgorithm.ToUpper(CultureInfo.InvariantCulture);
string mechanism = (string) algorithms[upper];
if (mechanism == null)
{
mechanism = upper;
}
switch (mechanism)
{
case "DHWITHSHA1KDF":
return new ECDHWithKdfBasicAgreement(
wrapAlgorithm,
new ECDHKekGenerator(
new Sha1Digest()));
}
throw new SecurityUtilityException("Basic Agreement (with KDF) " + agreeAlgorithm + " not recognised.");
}
public static string GetAlgorithmName(
DerObjectIdentifier oid)
{
return (string) algorithms[oid.Id];
}
}
}

View File

@@ -0,0 +1,566 @@
using System;
using System.Collections;
using System.Globalization;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Asn1.Kisa;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Ntt;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Agreement;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Encodings;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Macs;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Paddings;
namespace Org.BouncyCastle.Security
{
/// <remarks>
/// Cipher Utility class contains methods that can not be specifically grouped into other classes.
/// </remarks>
public sealed class CipherUtilities
{
private static readonly Hashtable algorithms = new Hashtable();
private static readonly Hashtable oids = new Hashtable();
static CipherUtilities()
{
// TODO Flesh out the list of aliases
algorithms[NistObjectIdentifiers.IdAes128Ecb.Id] = "AES/ECB/PKCS7PADDING";
algorithms[NistObjectIdentifiers.IdAes192Ecb.Id] = "AES/ECB/PKCS7PADDING";
algorithms[NistObjectIdentifiers.IdAes256Ecb.Id] = "AES/ECB/PKCS7PADDING";
algorithms["AES/ECB/PKCS7"] = "AES/ECB/PKCS7PADDING";
algorithms["AES//PKCS7"] = "AES/ECB/PKCS7PADDING";
algorithms["AES//PKCS7PADDING"] = "AES/ECB/PKCS7PADDING";
algorithms["AES/ECB/PKCS5"] = "AES/ECB/PKCS7PADDING";
algorithms["AES/ECB/PKCS5PADDING"] = "AES/ECB/PKCS7PADDING";
algorithms["AES//PKCS5"] = "AES/ECB/PKCS7PADDING";
algorithms["AES//PKCS5PADDING"] = "AES/ECB/PKCS7PADDING";
algorithms[NistObjectIdentifiers.IdAes128Cbc.Id] = "AES/CBC/PKCS7PADDING";
algorithms[NistObjectIdentifiers.IdAes192Cbc.Id] = "AES/CBC/PKCS7PADDING";
algorithms[NistObjectIdentifiers.IdAes256Cbc.Id] = "AES/CBC/PKCS7PADDING";
algorithms["AES/CBC/PKCS7"] = "AES/CBC/PKCS7PADDING";
algorithms["AES/CBC/PKCS5"] = "AES/CBC/PKCS7PADDING";
algorithms["AES/CBC/PKCS5PADDING"] = "AES/CBC/PKCS7PADDING";
algorithms[NistObjectIdentifiers.IdAes128Ofb.Id] = "AES/OFB/PKCS7PADDING";
algorithms[NistObjectIdentifiers.IdAes192Ofb.Id] = "AES/OFB/PKCS7PADDING";
algorithms[NistObjectIdentifiers.IdAes256Ofb.Id] = "AES/OFB/PKCS7PADDING";
algorithms["AES/OFB/PKCS7"] = "AES/OFB/PKCS7PADDING";
algorithms["AES/OFB/PKCS5"] = "AES/OFB/PKCS7PADDING";
algorithms["AES/OFB/PKCS5PADDING"] = "AES/OFB/PKCS7PADDING";
algorithms[NistObjectIdentifiers.IdAes128Cfb.Id] = "AES/CFB/PKCS7PADDING";
algorithms[NistObjectIdentifiers.IdAes192Cfb.Id] = "AES/CFB/PKCS7PADDING";
algorithms[NistObjectIdentifiers.IdAes256Cfb.Id] = "AES/CFB/PKCS7PADDING";
algorithms["AES/CFB/PKCS7"] = "AES/CFB/PKCS7PADDING";
algorithms["AES/CFB/PKCS5"] = "AES/CFB/PKCS7PADDING";
algorithms["AES/CFB/PKCS5PADDING"] = "AES/CFB/PKCS7PADDING";
algorithms["RSA//PKCS1"] = "RSA//PKCS1PADDING";
algorithms["RSA/ECB/PKCS1"] = "RSA//PKCS1PADDING";
algorithms["RSA/ECB/PKCS1PADDING"] = "RSA//PKCS1PADDING";
algorithms[PkcsObjectIdentifiers.RsaEncryption.Id] = "RSA//PKCS1PADDING";
algorithms[OiwObjectIdentifiers.DesCbc.Id] = "DES/CBC";
algorithms[PkcsObjectIdentifiers.DesEde3Cbc.Id] = "DESEDE/CBC";
algorithms[PkcsObjectIdentifiers.RC2Cbc.Id] = "RC2/CBC";
algorithms["1.3.6.1.4.1.188.7.1.1.2"] = "IDEA/CBC";
algorithms["1.2.840.113533.7.66.10"] = "CAST5/CBC";
algorithms["RC4"] = "ARC4";
algorithms["ARCFOUR"] = "ARC4";
algorithms["1.2.840.113549.3.4"] = "ARC4";
algorithms["PBEWITHSHA1AND128BITRC4"] = "PBEWITHSHAAND128BITRC4";
algorithms[PkcsObjectIdentifiers.PbeWithShaAnd128BitRC4.Id] = "PBEWITHSHAAND128BITRC4";
algorithms["PBEWITHSHA1AND40BITRC4"] = "PBEWITHSHAAND40BITRC4";
algorithms[PkcsObjectIdentifiers.PbeWithShaAnd40BitRC4.Id] = "PBEWITHSHAAND40BITRC4";
algorithms["PBEWITHSHA1ANDDES"] = "PBEWITHSHA1ANDDES-CBC";
algorithms[PkcsObjectIdentifiers.PbeWithSha1AndDesCbc.Id] = "PBEWITHSHA1ANDDES-CBC";
algorithms["PBEWITHSHA1ANDRC2"] = "PBEWITHSHA1ANDRC2-CBC";
algorithms[PkcsObjectIdentifiers.PbeWithSha1AndRC2Cbc.Id] = "PBEWITHSHA1ANDRC2-CBC";
algorithms["PBEWITHSHA1AND3-KEYTRIPLEDES-CBC"] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC";
algorithms["PBEWITHSHAAND3KEYTRIPLEDES"] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC";
algorithms[PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc.Id] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC";
algorithms["PBEWITHSHA1ANDDESEDE"] = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC";
algorithms["PBEWITHSHA1AND2-KEYTRIPLEDES-CBC"] = "PBEWITHSHAAND2-KEYTRIPLEDES-CBC";
algorithms[PkcsObjectIdentifiers.PbeWithShaAnd2KeyTripleDesCbc.Id] = "PBEWITHSHAAND2-KEYTRIPLEDES-CBC";
algorithms["PBEWITHSHA1AND128BITRC2-CBC"] = "PBEWITHSHAAND128BITRC2-CBC";
algorithms[PkcsObjectIdentifiers.PbeWithShaAnd128BitRC2Cbc.Id] = "PBEWITHSHAAND128BITRC2-CBC";
algorithms["PBEWITHSHA1AND40BITRC2-CBC"] = "PBEWITHSHAAND40BITRC2-CBC";
algorithms[PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc.Id] = "PBEWITHSHAAND40BITRC2-CBC";
algorithms["PBEWITHSHA1AND128BITAES-CBC-BC"] = "PBEWITHSHAAND128BITAES-CBC-BC";
algorithms["PBEWITHSHA-1AND128BITAES-CBC-BC"] = "PBEWITHSHAAND128BITAES-CBC-BC";
algorithms["PBEWITHSHA1AND192BITAES-CBC-BC"] = "PBEWITHSHAAND192BITAES-CBC-BC";
algorithms["PBEWITHSHA-1AND192BITAES-CBC-BC"] = "PBEWITHSHAAND192BITAES-CBC-BC";
algorithms["PBEWITHSHA1AND256BITAES-CBC-BC"] = "PBEWITHSHAAND256BITAES-CBC-BC";
algorithms["PBEWITHSHA-1AND256BITAES-CBC-BC"] = "PBEWITHSHAAND256BITAES-CBC-BC";
algorithms["PBEWITHSHA-256AND128BITAES-CBC-BC"] = "PBEWITHSHA256AND128BITAES-CBC-BC";
algorithms["PBEWITHSHA-256AND192BITAES-CBC-BC"] = "PBEWITHSHA256AND192BITAES-CBC-BC";
algorithms["PBEWITHSHA-256AND256BITAES-CBC-BC"] = "PBEWITHSHA256AND256BITAES-CBC-BC";
algorithms["GOST"] = "GOST28147";
algorithms["GOST-28147"] = "GOST28147";
algorithms[CryptoProObjectIdentifiers.GostR28147Cbc.Id] = "GOST28147/CBC/PKCS7PADDING";
algorithms["RC5-32"] = "RC5";
algorithms[NttObjectIdentifiers.IdCamellia128Cbc.Id] = "CAMELLIA/CBC/PKCS7PADDING";
algorithms[NttObjectIdentifiers.IdCamellia192Cbc.Id] = "CAMELLIA/CBC/PKCS7PADDING";
algorithms[NttObjectIdentifiers.IdCamellia256Cbc.Id] = "CAMELLIA/CBC/PKCS7PADDING";
algorithms[KisaObjectIdentifiers.IdSeedCbc.Id] = "SEED/CBC/PKCS7PADDING";
}
private CipherUtilities()
{
}
/// <summary>
/// Returns a ObjectIdentifier for a give encoding.
/// </summary>
/// <param name="mechanism">A string representation of the encoding.</param>
/// <returns>A DerObjectIdentifier, null if the Oid is not available.</returns>
// TODO Don't really want to support this
public static DerObjectIdentifier GetObjectIdentifier(
string mechanism)
{
if (mechanism == null)
throw new ArgumentNullException("mechanism");
mechanism = mechanism.ToUpper(CultureInfo.InvariantCulture);
string aliased = (string) algorithms[mechanism];
if (aliased != null)
mechanism = aliased;
return (DerObjectIdentifier) oids[mechanism];
}
public static ICollection Algorithms
{
get { return oids.Keys; }
}
public static IBufferedCipher GetCipher(
DerObjectIdentifier oid)
{
return GetCipher(oid.Id);
}
public static IBufferedCipher GetCipher(
string algorithm)
{
if (algorithm == null)
throw new ArgumentNullException("algorithm");
algorithm = algorithm.ToUpper(CultureInfo.InvariantCulture);
string aliased = (string) algorithms[algorithm];
if (aliased != null)
algorithm = aliased;
IBasicAgreement iesAgreement = null;
if (algorithm == "IES")
{
iesAgreement = new DHBasicAgreement();
}
else if (algorithm == "ECIES")
{
iesAgreement = new ECDHBasicAgreement();
}
if (iesAgreement != null)
{
return new BufferedIesCipher(
new IesEngine(
iesAgreement,
new Kdf2BytesGenerator(
new Sha1Digest()),
new HMac(
new Sha1Digest())));
}
if (algorithm.StartsWith("PBE"))
{
switch (algorithm)
{
case "PBEWITHSHAAND2-KEYTRIPLEDES-CBC":
case "PBEWITHSHAAND3-KEYTRIPLEDES-CBC":
return new PaddedBufferedBlockCipher(
new CbcBlockCipher(new DesEdeEngine()));
case "PBEWITHSHAAND128BITRC2-CBC":
case "PBEWITHSHAAND40BITRC2-CBC":
return new PaddedBufferedBlockCipher(
new CbcBlockCipher(new RC2Engine()));
case "PBEWITHSHAAND128BITAES-CBC-BC":
case "PBEWITHSHAAND192BITAES-CBC-BC":
case "PBEWITHSHAAND256BITAES-CBC-BC":
case "PBEWITHSHA256AND128BITAES-CBC-BC":
case "PBEWITHSHA256AND192BITAES-CBC-BC":
case "PBEWITHSHA256AND256BITAES-CBC-BC":
case "PBEWITHMD5AND128BITAES-CBC-OPENSSL":
case "PBEWITHMD5AND192BITAES-CBC-OPENSSL":
case "PBEWITHMD5AND256BITAES-CBC-OPENSSL":
return new PaddedBufferedBlockCipher(
new CbcBlockCipher(new AesFastEngine()));
case "PBEWITHSHA1ANDDES-CBC":
return new PaddedBufferedBlockCipher(
new CbcBlockCipher(new DesEngine()));
case "PBEWITHSHA1ANDRC2-CBC":
return new PaddedBufferedBlockCipher(
new CbcBlockCipher(new RC2Engine()));
}
}
string[] parts = algorithm.Split('/');
IBlockCipher blockCipher = null;
IAsymmetricBlockCipher asymBlockCipher = null;
IStreamCipher streamCipher = null;
switch (parts[0])
{
case "AES":
blockCipher = new AesFastEngine();
break;
case "ARC4":
streamCipher = new RC4Engine();
break;
case "BLOWFISH":
blockCipher = new BlowfishEngine();
break;
case "CAMELLIA":
blockCipher = new CamelliaEngine();
break;
case "CAST5":
blockCipher = new Cast5Engine();
break;
case "CAST6":
blockCipher = new Cast6Engine();
break;
case "DES":
blockCipher = new DesEngine();
break;
case "DESEDE":
blockCipher = new DesEdeEngine();
break;
case "ELGAMAL":
asymBlockCipher = new ElGamalEngine();
break;
case "GOST28147":
blockCipher = new Gost28147Engine();
break;
case "HC128":
streamCipher = new HC128Engine();
break;
case "HC256":
streamCipher = new HC256Engine();
break;
case "IDEA":
blockCipher = new IdeaEngine();
break;
case "NOEKEON":
blockCipher = new NoekeonEngine();
break;
case "PBEWITHSHAAND128BITRC4":
case "PBEWITHSHAAND40BITRC4":
streamCipher = new RC4Engine();
break;
case "RC2":
blockCipher = new RC2Engine();
break;
case "RC5":
blockCipher = new RC532Engine();
break;
case "RC5-64":
blockCipher = new RC564Engine();
break;
case "RC6":
blockCipher = new RC6Engine();
break;
case "RIJNDAEL":
blockCipher = new RijndaelEngine();
break;
case "RSA":
asymBlockCipher = new RsaBlindedEngine();
break;
case "SALSA20":
streamCipher = new Salsa20Engine();
break;
case "SEED":
blockCipher = new SeedEngine();
break;
case "SERPENT":
blockCipher = new SerpentEngine();
break;
case "SKIPJACK":
blockCipher = new SkipjackEngine();
break;
case "TEA":
blockCipher = new TeaEngine();
break;
case "TWOFISH":
blockCipher = new TwofishEngine();
break;
case "VMPC":
streamCipher = new VmpcEngine();
break;
case "VMPC-KSA3":
streamCipher = new VmpcKsa3Engine();
break;
case "XTEA":
blockCipher = new XteaEngine();
break;
default:
throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
}
if (streamCipher != null)
{
if (parts.Length > 1)
throw new ArgumentException("Modes and paddings not used for stream ciphers");
return new BufferedStreamCipher(streamCipher);
}
bool cts = false;
bool padded = true;
IBlockCipherPadding padding = null;
IAeadBlockCipher aeadBlockCipher = null;
if (parts.Length > 2)
{
if (streamCipher != null)
throw new ArgumentException("Paddings not used for stream ciphers");
switch (parts[2])
{
case "NOPADDING":
padded = false;
break;
case "":
case "RAW":
break;
case "ISO10126PADDING":
case "ISO10126D2PADDING":
case "ISO10126-2PADDING":
padding = new ISO10126d2Padding();
break;
case "ISO7816-4PADDING":
case "ISO9797-1PADDING":
padding = new ISO7816d4Padding();
break;
case "ISO9796-1":
case "ISO9796-1PADDING":
asymBlockCipher = new ISO9796d1Encoding(asymBlockCipher);
break;
case "OAEP":
case "OAEPPADDING":
asymBlockCipher = new OaepEncoding(asymBlockCipher);
break;
case "OAEPWITHMD5ANDMGF1PADDING":
asymBlockCipher = new OaepEncoding(asymBlockCipher, new MD5Digest());
break;
case "OAEPWITHSHA1ANDMGF1PADDING":
asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha1Digest());
break;
case "OAEPWITHSHA224ANDMGF1PADDING":
asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha224Digest());
break;
case "OAEPWITHSHA256ANDMGF1PADDING":
asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha256Digest());
break;
case "OAEPWITHSHA384ANDMGF1PADDING":
asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha384Digest());
break;
case "OAEPWITHSHA512ANDMGF1PADDING":
asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha512Digest());
break;
case "PKCS1":
case "PKCS1PADDING":
asymBlockCipher = new Pkcs1Encoding(asymBlockCipher);
break;
case "PKCS5":
case "PKCS5PADDING":
case "PKCS7":
case "PKCS7PADDING":
// NB: Padding defaults to Pkcs7Padding already
break;
case "TBCPADDING":
padding = new TbcPadding();
break;
case "WITHCTS":
cts = true;
break;
case "X9.23PADDING":
case "X923PADDING":
padding = new X923Padding();
break;
case "ZEROBYTEPADDING":
padding = new ZeroBytePadding();
break;
default:
throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
}
}
string mode = "";
if (parts.Length > 1)
{
mode = parts[1];
int di = GetDigitIndex(mode);
string modeName = di >= 0 ? mode.Substring(0, di) : mode;
switch (modeName)
{
case "":
case "ECB":
case "NONE":
break;
case "CBC":
blockCipher = new CbcBlockCipher(blockCipher);
break;
case "CCM":
aeadBlockCipher = new CcmBlockCipher(blockCipher);
break;
case "CFB":
{
int bits = (di < 0)
? 8 * blockCipher.GetBlockSize()
: int.Parse(mode.Substring(di));
blockCipher = new CfbBlockCipher(blockCipher, bits);
break;
}
case "CTR":
blockCipher = new SicBlockCipher(blockCipher);
break;
case "CTS":
cts = true;
blockCipher = new CbcBlockCipher(blockCipher);
break;
case "EAX":
aeadBlockCipher = new EaxBlockCipher(blockCipher);
break;
case "GCM":
aeadBlockCipher = new GcmBlockCipher(blockCipher);
break;
case "GOFB":
blockCipher = new GOfbBlockCipher(blockCipher);
break;
case "OFB":
{
int bits = (di < 0)
? 8 * blockCipher.GetBlockSize()
: int.Parse(mode.Substring(di));
blockCipher = new OfbBlockCipher(blockCipher, bits);
break;
}
case "OPENPGPCFB":
blockCipher = new OpenPgpCfbBlockCipher(blockCipher);
break;
case "SIC":
if (blockCipher.GetBlockSize() < 16)
{
throw new ArgumentException("Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)");
}
blockCipher = new SicBlockCipher(blockCipher);
break;
default:
throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
}
}
if (aeadBlockCipher != null)
{
if (cts)
throw new SecurityUtilityException("CTS mode not valid for AEAD ciphers.");
if (padded && parts.Length > 1 && parts[2] != "")
throw new SecurityUtilityException("Bad padding specified for AEAD cipher.");
return new BufferedAeadBlockCipher(aeadBlockCipher);
}
if (blockCipher != null)
{
if (cts)
{
return new CtsBlockCipher(blockCipher);
}
if (!padded || blockCipher.IsPartialBlockOkay)
{
return new BufferedBlockCipher(blockCipher);
}
if (padding != null)
{
return new PaddedBufferedBlockCipher(blockCipher, padding);
}
return new PaddedBufferedBlockCipher(blockCipher);
}
if (asymBlockCipher != null)
{
return new BufferedAsymmetricBlockCipher(asymBlockCipher);
}
throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
}
public static string GetAlgorithmName(
DerObjectIdentifier oid)
{
return (string) algorithms[oid.Id];
}
private static int GetDigitIndex(
string s)
{
for (int i = 0; i < s.Length; ++i)
{
if (char.IsDigit(s[i]))
return i;
}
return -1;
}
}
}

View File

@@ -0,0 +1,150 @@
using System.Collections;
using System.Globalization;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.TeleTrust;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto;
namespace Org.BouncyCastle.Security
{
/// <remarks>
/// Utility class for creating IDigest objects from their names/Oids
/// </remarks>
public sealed class DigestUtilities
{
private DigestUtilities()
{
}
private static readonly Hashtable algorithms = new Hashtable();
private static readonly Hashtable oids = new Hashtable();
static DigestUtilities()
{
algorithms[PkcsObjectIdentifiers.MD2.Id] = "MD2";
algorithms[PkcsObjectIdentifiers.MD4.Id] = "MD4";
algorithms[PkcsObjectIdentifiers.MD5.Id] = "MD5";
algorithms["SHA1"] = "SHA-1";
algorithms[OiwObjectIdentifiers.IdSha1.Id] = "SHA-1";
algorithms["SHA224"] = "SHA-224";
algorithms[NistObjectIdentifiers.IdSha224.Id] = "SHA-224";
algorithms["SHA256"] = "SHA-256";
algorithms[NistObjectIdentifiers.IdSha256.Id] = "SHA-256";
algorithms["SHA384"] = "SHA-384";
algorithms[NistObjectIdentifiers.IdSha384.Id] = "SHA-384";
algorithms["SHA512"] = "SHA-512";
algorithms[NistObjectIdentifiers.IdSha512.Id] = "SHA-512";
algorithms["RIPEMD-128"] = "RIPEMD128";
algorithms[TeleTrusTObjectIdentifiers.RipeMD128.Id] = "RIPEMD128";
algorithms["RIPEMD-160"] = "RIPEMD160";
algorithms[TeleTrusTObjectIdentifiers.RipeMD160.Id] = "RIPEMD160";
algorithms["RIPEMD-256"] = "RIPEMD256";
algorithms[TeleTrusTObjectIdentifiers.RipeMD256.Id] = "RIPEMD256";
algorithms["RIPEMD-320"] = "RIPEMD320";
// algorithms[TeleTrusTObjectIdentifiers.RipeMD320.Id] = "RIPEMD320";
algorithms[CryptoProObjectIdentifiers.GostR3411.Id] = "GOST3411";
oids["MD2"] = PkcsObjectIdentifiers.MD2;
oids["MD4"] = PkcsObjectIdentifiers.MD4;
oids["MD5"] = PkcsObjectIdentifiers.MD5;
oids["SHA-1"] = OiwObjectIdentifiers.IdSha1;
oids["SHA-224"] = NistObjectIdentifiers.IdSha224;
oids["SHA-256"] = NistObjectIdentifiers.IdSha256;
oids["SHA-384"] = NistObjectIdentifiers.IdSha384;
oids["SHA-512"] = NistObjectIdentifiers.IdSha512;
oids["RIPEMD128"] = TeleTrusTObjectIdentifiers.RipeMD128;
oids["RIPEMD160"] = TeleTrusTObjectIdentifiers.RipeMD160;
oids["RIPEMD256"] = TeleTrusTObjectIdentifiers.RipeMD256;
oids["GOST3411"] = CryptoProObjectIdentifiers.GostR3411;
}
/// <summary>
/// Returns a ObjectIdentifier for a given digest mechanism.
/// </summary>
/// <param name="mechanism">A string representation of the digest meanism.</param>
/// <returns>A DerObjectIdentifier, null if the Oid is not available.</returns>
public static DerObjectIdentifier GetObjectIdentifier(
string mechanism)
{
mechanism = (string) algorithms[mechanism.ToUpper(CultureInfo.InvariantCulture)];
if (mechanism != null)
{
return (DerObjectIdentifier)oids[mechanism];
}
return null;
}
public static ICollection Algorithms
{
get { return oids.Keys; }
}
public static IDigest GetDigest(
DerObjectIdentifier id)
{
return GetDigest(id.Id);
}
public static IDigest GetDigest(
string algorithm)
{
string upper = algorithm.ToUpper(CultureInfo.InvariantCulture);
string mechanism = (string) algorithms[upper];
if (mechanism == null)
{
mechanism = upper;
}
switch (mechanism)
{
case "GOST3411": return new Gost3411Digest();
case "MD2": return new MD2Digest();
case "MD4": return new MD4Digest();
case "MD5": return new MD5Digest();
case "RIPEMD128": return new RipeMD128Digest();
case "RIPEMD160": return new RipeMD160Digest();
case "RIPEMD256": return new RipeMD256Digest();
case "RIPEMD320": return new RipeMD320Digest();
case "SHA-1": return new Sha1Digest();
case "SHA-224": return new Sha224Digest();
case "SHA-256": return new Sha256Digest();
case "SHA-384": return new Sha384Digest();
case "SHA-512": return new Sha512Digest();
case "TIGER": return new TigerDigest();
case "WHIRLPOOL": return new WhirlpoolDigest();
default:
throw new SecurityUtilityException("Digest " + mechanism + " not recognised.");
}
}
public static string GetAlgorithmName(
DerObjectIdentifier oid)
{
return (string) algorithms[oid.Id];
}
public static byte[] DoFinal(
IDigest digest)
{
byte[] b = new byte[digest.GetDigestSize()];
digest.DoFinal(b, 0);
return b;
}
}
}

View File

@@ -0,0 +1,163 @@
#if !NETCF_1_0
using System;
using System.Security.Cryptography;
using SystemX509 = System.Security.Cryptography.X509Certificates;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.X509;
namespace Org.BouncyCastle.Security
{
/// <summary>
/// A class containing methods to interface the BouncyCastle world to the .NET Crypto world.
/// </summary>
public sealed class DotNetUtilities
{
private DotNetUtilities()
{
}
/// <summary>
/// Create an System.Security.Cryptography.X509Certificate from an X509Certificate Structure.
/// </summary>
/// <param name="x509Struct"></param>
/// <returns>A System.Security.Cryptography.X509Certificate.</returns>
public static SystemX509.X509Certificate ToX509Certificate(
X509CertificateStructure x509Struct)
{
return new SystemX509.X509Certificate(x509Struct.GetDerEncoded());
}
public static SystemX509.X509Certificate ToX509Certificate(
X509Certificate x509Cert)
{
return new SystemX509.X509Certificate(x509Cert.GetEncoded());
}
public static X509Certificate FromX509Certificate(
SystemX509.X509Certificate x509Cert)
{
return new X509CertificateParser().ReadCertificate(x509Cert.GetRawCertData());
}
public static AsymmetricCipherKeyPair GetDsaKeyPair(
DSACryptoServiceProvider dsaCsp)
{
return GetDsaKeyPair(dsaCsp.ExportParameters(true));
}
public static AsymmetricCipherKeyPair GetDsaKeyPair(
DSAParameters dp)
{
DsaValidationParameters validationParameters = (dp.Seed != null)
? new DsaValidationParameters(dp.Seed, dp.Counter)
: null;
DsaParameters parameters = new DsaParameters(
new BigInteger(1, dp.P),
new BigInteger(1, dp.Q),
new BigInteger(1, dp.G),
validationParameters);
DsaPublicKeyParameters pubKey = new DsaPublicKeyParameters(
new BigInteger(1, dp.Y),
parameters);
DsaPrivateKeyParameters privKey = new DsaPrivateKeyParameters(
new BigInteger(1, dp.X),
parameters);
return new AsymmetricCipherKeyPair(pubKey, privKey);
}
public static DsaPublicKeyParameters GetDsaPublicKey(
DSACryptoServiceProvider dsaCsp)
{
return GetDsaPublicKey(dsaCsp.ExportParameters(false));
}
public static DsaPublicKeyParameters GetDsaPublicKey(
DSAParameters dp)
{
DsaValidationParameters validationParameters = (dp.Seed != null)
? new DsaValidationParameters(dp.Seed, dp.Counter)
: null;
DsaParameters parameters = new DsaParameters(
new BigInteger(1, dp.P),
new BigInteger(1, dp.Q),
new BigInteger(1, dp.G),
validationParameters);
return new DsaPublicKeyParameters(
new BigInteger(1, dp.Y),
parameters);
}
public static AsymmetricCipherKeyPair GetRsaKeyPair(
RSACryptoServiceProvider rsaCsp)
{
return GetRsaKeyPair(rsaCsp.ExportParameters(true));
}
public static AsymmetricCipherKeyPair GetRsaKeyPair(
RSAParameters rp)
{
BigInteger modulus = new BigInteger(1, rp.Modulus);
BigInteger pubExp = new BigInteger(1, rp.Exponent);
RsaKeyParameters pubKey = new RsaKeyParameters(
false,
modulus,
pubExp);
RsaPrivateCrtKeyParameters privKey = new RsaPrivateCrtKeyParameters(
modulus,
pubExp,
new BigInteger(1, rp.D),
new BigInteger(1, rp.P),
new BigInteger(1, rp.Q),
new BigInteger(1, rp.DP),
new BigInteger(1, rp.DQ),
new BigInteger(1, rp.InverseQ));
return new AsymmetricCipherKeyPair(pubKey, privKey);
}
public static RsaKeyParameters GetRsaPublicKey(
RSACryptoServiceProvider rsaCsp)
{
return GetRsaPublicKey(rsaCsp.ExportParameters(false));
}
public static RsaKeyParameters GetRsaPublicKey(
RSAParameters rp)
{
return new RsaKeyParameters(
false,
new BigInteger(1, rp.Modulus),
new BigInteger(1, rp.Exponent));
}
public static AsymmetricCipherKeyPair GetKeyPair(AsymmetricAlgorithm privateKey)
{
if (privateKey is DSACryptoServiceProvider)
{
return GetDsaKeyPair((DSACryptoServiceProvider) privateKey);
}
if (privateKey is RSACryptoServiceProvider)
{
return GetRsaKeyPair((RSACryptoServiceProvider) privateKey);
}
throw new ArgumentException("Unsupported algorithm specified", "privateKey");
}
}
}
#endif

View File

@@ -0,0 +1,26 @@
using System;
namespace Org.BouncyCastle.Security
{
public class GeneralSecurityException
: Exception
{
public GeneralSecurityException()
: base()
{
}
public GeneralSecurityException(
string message)
: base(message)
{
}
public GeneralSecurityException(
string message,
Exception exception)
: base(message, exception)
{
}
}
}

View File

@@ -0,0 +1,352 @@
using System.Collections;
using System.Globalization;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Asn1.Iana;
using Org.BouncyCastle.Asn1.Kisa;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Ntt;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
namespace Org.BouncyCastle.Security
{
public sealed class GeneratorUtilities
{
private GeneratorUtilities()
{
}
private static readonly Hashtable kgAlgorithms = new Hashtable();
private static readonly Hashtable kpgAlgorithms = new Hashtable();
static GeneratorUtilities()
{
//
// key generators.
//
AddKgAlgorithm("AES",
"AESWRAP");
AddKgAlgorithm("AES128",
"2.16.840.1.101.3.4.2",
NistObjectIdentifiers.IdAes128Cbc,
NistObjectIdentifiers.IdAes128Cfb,
NistObjectIdentifiers.IdAes128Ecb,
NistObjectIdentifiers.IdAes128Ofb,
NistObjectIdentifiers.IdAes128Wrap);
AddKgAlgorithm("AES192",
"2.16.840.1.101.3.4.22",
NistObjectIdentifiers.IdAes192Cbc,
NistObjectIdentifiers.IdAes192Cfb,
NistObjectIdentifiers.IdAes192Ecb,
NistObjectIdentifiers.IdAes192Ofb,
NistObjectIdentifiers.IdAes192Wrap);
AddKgAlgorithm("AES256",
"2.16.840.1.101.3.4.42",
NistObjectIdentifiers.IdAes256Cbc,
NistObjectIdentifiers.IdAes256Cfb,
NistObjectIdentifiers.IdAes256Ecb,
NistObjectIdentifiers.IdAes256Ofb,
NistObjectIdentifiers.IdAes256Wrap);
AddKgAlgorithm("BLOWFISH");
AddKgAlgorithm("CAMELLIA",
"CAMELLIAWRAP");
AddKgAlgorithm("CAMELLIA128",
NttObjectIdentifiers.IdCamellia128Cbc,
NttObjectIdentifiers.IdCamellia128Wrap);
AddKgAlgorithm("CAMELLIA192",
NttObjectIdentifiers.IdCamellia192Cbc,
NttObjectIdentifiers.IdCamellia192Wrap);
AddKgAlgorithm("CAMELLIA256",
NttObjectIdentifiers.IdCamellia256Cbc,
NttObjectIdentifiers.IdCamellia256Wrap);
AddKgAlgorithm("CAST5",
"1.2.840.113533.7.66.10");
AddKgAlgorithm("CAST6");
AddKgAlgorithm("DES",
OiwObjectIdentifiers.DesCbc);
AddKgAlgorithm("DESEDE",
"DESEDEWRAP",
PkcsObjectIdentifiers.IdAlgCms3DesWrap);
AddKgAlgorithm("DESEDE3",
PkcsObjectIdentifiers.DesEde3Cbc);
AddKgAlgorithm("GOST28147",
"GOST",
"GOST-28147",
CryptoProObjectIdentifiers.GostR28147Cbc);
AddKgAlgorithm("HC128");
AddKgAlgorithm("HC256");
AddKgAlgorithm("IDEA",
"1.3.6.1.4.1.188.7.1.1.2");
AddKgAlgorithm("NOEKEON");
AddKgAlgorithm("RC2",
PkcsObjectIdentifiers.RC2Cbc,
PkcsObjectIdentifiers.IdAlgCmsRC2Wrap);
AddKgAlgorithm("RC4",
"ARC4",
"1.2.840.113549.3.4");
AddKgAlgorithm("RC5",
"RC5-32");
AddKgAlgorithm("RC5-64");
AddKgAlgorithm("RC6");
AddKgAlgorithm("RIJNDAEL");
AddKgAlgorithm("SALSA20");
AddKgAlgorithm("SEED",
KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap,
KisaObjectIdentifiers.IdSeedCbc);
AddKgAlgorithm("SERPENT");
AddKgAlgorithm("SKIPJACK");
AddKgAlgorithm("TEA");
AddKgAlgorithm("TWOFISH");
AddKgAlgorithm("VMPC");
AddKgAlgorithm("VMPC-KSA3");
AddKgAlgorithm("XTEA");
//
// HMac key generators
//
AddHMacKeyGenerator("MD2");
AddHMacKeyGenerator("MD4");
AddHMacKeyGenerator("MD5",
IanaObjectIdentifiers.HmacMD5);
AddHMacKeyGenerator("SHA1",
PkcsObjectIdentifiers.IdHmacWithSha1,
IanaObjectIdentifiers.HmacSha1);
AddHMacKeyGenerator("SHA224",
PkcsObjectIdentifiers.IdHmacWithSha224);
AddHMacKeyGenerator("SHA256",
PkcsObjectIdentifiers.IdHmacWithSha256);
AddHMacKeyGenerator("SHA384",
PkcsObjectIdentifiers.IdHmacWithSha384);
AddHMacKeyGenerator("SHA512",
PkcsObjectIdentifiers.IdHmacWithSha512);
AddHMacKeyGenerator("RIPEMD128");
AddHMacKeyGenerator("RIPEMD160",
IanaObjectIdentifiers.HmacRipeMD160);
AddHMacKeyGenerator("TIGER",
IanaObjectIdentifiers.HmacTiger);
//
// key pair generators.
//
AddKpgAlgorithm("DH");
AddKpgAlgorithm("DSA");
AddKpgAlgorithm("EC");
AddKpgAlgorithm("ECDH",
"ECIES");
AddKpgAlgorithm("ECDHC");
AddKpgAlgorithm("ECDSA");
AddKpgAlgorithm("ECGOST3410",
"ECGOST-3410",
"GOST-3410-2001");
AddKpgAlgorithm("ELGAMAL");
AddKpgAlgorithm("GOST3410",
"GOST-3410",
"GOST-3410-94");
AddKpgAlgorithm("RSA",
"1.2.840.113549.1.1.1");
}
private static void AddKgAlgorithm(
string canonicalName,
params object[] aliases)
{
kgAlgorithms[canonicalName] = canonicalName;
foreach (object alias in aliases)
{
kgAlgorithms[alias.ToString()] = canonicalName;
}
}
private static void AddKpgAlgorithm(
string canonicalName,
params object[] aliases)
{
kpgAlgorithms[canonicalName] = canonicalName;
foreach (object alias in aliases)
{
kpgAlgorithms[alias.ToString()] = canonicalName;
}
}
private static void AddHMacKeyGenerator(
string algorithm,
params object[] aliases)
{
string mainName = "HMAC" + algorithm;
kgAlgorithms[mainName] = mainName;
kgAlgorithms["HMAC-" + algorithm] = mainName;
kgAlgorithms["HMAC/" + algorithm] = mainName;
foreach (object alias in aliases)
{
kgAlgorithms[alias.ToString()] = mainName;
}
}
// TODO Consider making this public
internal static string GetCanonicalKeyGeneratorAlgorithm(
string algorithm)
{
return (string) kgAlgorithms[algorithm.ToUpper(CultureInfo.InvariantCulture)];
}
// TODO Consider making this public
internal static string GetCanonicalKeyPairGeneratorAlgorithm(
string algorithm)
{
return (string) kpgAlgorithms[algorithm.ToUpper(CultureInfo.InvariantCulture)];
}
public static CipherKeyGenerator GetKeyGenerator(
DerObjectIdentifier oid)
{
return GetKeyGenerator(oid.Id);
}
public static CipherKeyGenerator GetKeyGenerator(
string algorithm)
{
string canonicalName = GetCanonicalKeyGeneratorAlgorithm(algorithm);
if (canonicalName == null)
throw new SecurityUtilityException("KeyGenerator " + algorithm + " not recognised.");
switch (canonicalName)
{
case "DES":
return new DesKeyGenerator(64);
case "DESEDE":
return new DesEdeKeyGenerator(128);
case "DESEDE3":
return new DesEdeKeyGenerator(192);
case "AES":
return new CipherKeyGenerator(192);
case "AES128":
return new CipherKeyGenerator(128);
case "AES192":
return new CipherKeyGenerator(192);
case "AES256":
return new CipherKeyGenerator(256);
case "BLOWFISH":
return new CipherKeyGenerator(448);
case "CAMELLIA":
return new CipherKeyGenerator(256);
case "CAMELLIA128":
return new CipherKeyGenerator(128);
case "CAMELLIA192":
return new CipherKeyGenerator(192);
case "CAMELLIA256":
return new CipherKeyGenerator(256);
case "CAST5":
return new CipherKeyGenerator(128);
case "CAST6":
return new CipherKeyGenerator(256);
case "GOST28147":
return new CipherKeyGenerator(256);
case "HC128":
return new CipherKeyGenerator(128);
case "HC256":
return new CipherKeyGenerator(256);
case "HMACMD2":
case "HMACMD4":
case "HMACMD5":
return new CipherKeyGenerator(128);
case "HMACSHA1":
return new CipherKeyGenerator(160);
case "HMACSHA224":
return new CipherKeyGenerator(224);
case "HMACSHA256":
return new CipherKeyGenerator(256);
case "HMACSHA384":
return new CipherKeyGenerator(384);
case "HMACSHA512":
return new CipherKeyGenerator(512);
case "HMACRIPEMD128":
return new CipherKeyGenerator(128);
case "HMACRIPEMD160":
return new CipherKeyGenerator(160);
case "HMACTIGER":
return new CipherKeyGenerator(192);
case "IDEA":
return new CipherKeyGenerator(128);
case "NOEKEON":
return new CipherKeyGenerator(128);
case "RC2":
case "RC4":
case "RC5":
return new CipherKeyGenerator(128);
case "RC5-64":
case "RC6":
return new CipherKeyGenerator(256);
case "RIJNDAEL":
return new CipherKeyGenerator(192);
case "SALSA20":
return new CipherKeyGenerator(128);
case "SEED":
return new CipherKeyGenerator(128);
case "SERPENT":
return new CipherKeyGenerator(192);
case "SKIPJACK":
return new CipherKeyGenerator(80);
case "TEA":
case "XTEA":
return new CipherKeyGenerator(128);
case "TWOFISH":
return new CipherKeyGenerator(256);
case "VMPC":
case "VMPC-KSA3":
return new CipherKeyGenerator(128);
}
throw new SecurityUtilityException("KeyGenerator " + algorithm + " not recognised.");
}
public static IAsymmetricCipherKeyPairGenerator GetKeyPairGenerator(
DerObjectIdentifier oid)
{
return GetKeyPairGenerator(oid.Id);
}
public static IAsymmetricCipherKeyPairGenerator GetKeyPairGenerator(
string algorithm)
{
string canonicalName = GetCanonicalKeyPairGeneratorAlgorithm(algorithm);
if (canonicalName == null)
throw new SecurityUtilityException("KeyPairGenerator " + algorithm + " not recognised.");
switch (canonicalName)
{
case "DH":
return new DHKeyPairGenerator();
case "DSA":
return new DsaKeyPairGenerator();
case "EC":
case "ECDH":
case "ECDHC":
case "ECDSA":
case "ECGOST3410":
return new ECKeyPairGenerator(canonicalName);
case "ELGAMAL":
return new ElGamalKeyPairGenerator();
case "GOST3410":
return new Gost3410KeyPairGenerator();
case "RSA":
return new RsaKeyPairGenerator();
default:
break;
}
throw new SecurityUtilityException("KeyPairGenerator " + algorithm + " not recognised.");
}
}
}

View File

@@ -0,0 +1,11 @@
using System;
namespace Org.BouncyCastle.Security
{
public class InvalidKeyException : KeyException
{
public InvalidKeyException() : base() { }
public InvalidKeyException(string message) : base(message) { }
public InvalidKeyException(string message, Exception exception) : base(message, exception) { }
}
}

View File

@@ -0,0 +1,11 @@
using System;
namespace Org.BouncyCastle.Security
{
public class InvalidParameterException : KeyException
{
public InvalidParameterException() : base() { }
public InvalidParameterException(string message) : base(message) { }
public InvalidParameterException(string message, Exception exception) : base(message, exception) { }
}
}

View File

@@ -0,0 +1,11 @@
using System;
namespace Org.BouncyCastle.Security
{
public class KeyException : GeneralSecurityException
{
public KeyException() : base() { }
public KeyException(string message) : base(message) { }
public KeyException(string message, Exception exception) : base(message, exception) { }
}
}

View File

@@ -0,0 +1,220 @@
using System.Collections;
using System.Globalization;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Iana;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Macs;
using Org.BouncyCastle.Crypto.Paddings;
namespace Org.BouncyCastle.Security
{
/// <remarks>
/// Utility class for creating HMac object from their names/Oids
/// </remarks>
public sealed class MacUtilities
{
private MacUtilities()
{
}
private static readonly Hashtable algorithms = new Hashtable();
// private static readonly Hashtable oids = new Hashtable();
static MacUtilities()
{
algorithms[IanaObjectIdentifiers.HmacMD5.Id] = "HMAC-MD5";
algorithms[IanaObjectIdentifiers.HmacRipeMD160.Id] = "HMAC-RIPEMD160";
algorithms[IanaObjectIdentifiers.HmacSha1.Id] = "HMAC-SHA1";
algorithms[IanaObjectIdentifiers.HmacTiger.Id] = "HMAC-TIGER";
algorithms[PkcsObjectIdentifiers.IdHmacWithSha1.Id] = "HMAC-SHA1";
algorithms[PkcsObjectIdentifiers.IdHmacWithSha224.Id] = "HMAC-SHA224";
algorithms[PkcsObjectIdentifiers.IdHmacWithSha256.Id] = "HMAC-SHA256";
algorithms[PkcsObjectIdentifiers.IdHmacWithSha384.Id] = "HMAC-SHA384";
algorithms[PkcsObjectIdentifiers.IdHmacWithSha512.Id] = "HMAC-SHA512";
algorithms["DES"] = "DESMAC";
algorithms["DES/CFB8"] = "DESMAC/CFB8";
algorithms["DESEDE"] = "DESEDEMAC";
algorithms["DESEDE/CFB8"] = "DESEDEMAC/CFB8";
algorithms["DESISO9797MAC"] = "DESWITHISO9797";
algorithms["DESEDE64"] = "DESEDEMAC64";
algorithms["DESEDE64WITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING";
algorithms["DESEDEISO9797ALG1MACWITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING";
algorithms["DESEDEISO9797ALG1WITHISO7816-4PADDING"] = "DESEDEMAC64WITHISO7816-4PADDING";
algorithms["ISO9797ALG3"] = "ISO9797ALG3MAC";
algorithms["ISO9797ALG3MACWITHISO7816-4PADDING"] = "ISO9797ALG3WITHISO7816-4PADDING";
algorithms["SKIPJACK"] = "SKIPJACKMAC";
algorithms["SKIPJACK/CFB8"] = "SKIPJACKMAC/CFB8";
algorithms["IDEA"] = "IDEAMAC";
algorithms["IDEA/CFB8"] = "IDEAMAC/CFB8";
algorithms["RC2"] = "RC2MAC";
algorithms["RC2/CFB8"] = "RC2MAC/CFB8";
algorithms["RC5"] = "RC5MAC";
algorithms["RC5/CFB8"] = "RC5MAC/CFB8";
algorithms["GOST28147"] = "GOST28147MAC";
algorithms["VMPC"] = "VMPCMAC";
algorithms["VMPC-MAC"] = "VMPCMAC";
algorithms["PBEWITHHMACSHA"] = "PBEWITHHMACSHA1";
algorithms["1.3.14.3.2.26"] = "PBEWITHHMACSHA1";
}
// /// <summary>
// /// Returns a ObjectIdentifier for a given digest mechanism.
// /// </summary>
// /// <param name="mechanism">A string representation of the digest meanism.</param>
// /// <returns>A DerObjectIdentifier, null if the Oid is not available.</returns>
// public static DerObjectIdentifier GetObjectIdentifier(
// string mechanism)
// {
// mechanism = (string) algorithms[mechanism.ToUpper(CultureInfo.InvariantCulture)];
//
// if (mechanism != null)
// {
// return (DerObjectIdentifier)oids[mechanism];
// }
//
// return null;
// }
// public static ICollection Algorithms
// {
// get { return oids.Keys; }
// }
public static IMac GetMac(
DerObjectIdentifier id)
{
return GetMac(id.Id);
}
public static IMac GetMac(
string algorithm)
{
string upper = algorithm.ToUpper(CultureInfo.InvariantCulture);
string mechanism = (string) algorithms[upper];
if (mechanism == null)
{
mechanism = upper;
}
if (mechanism.StartsWith("PBEWITH"))
{
mechanism = mechanism.Substring("PBEWITH".Length);
}
if (mechanism.StartsWith("HMAC"))
{
string digestName;
if (mechanism.StartsWith("HMAC-") || mechanism.StartsWith("HMAC/"))
{
digestName = mechanism.Substring(5);
}
else
{
digestName = mechanism.Substring(4);
}
return new HMac(DigestUtilities.GetDigest(digestName));
}
if (mechanism == "DESMAC")
{
return new CbcBlockCipherMac(new DesEngine());
}
if (mechanism == "DESMAC/CFB8")
{
return new CfbBlockCipherMac(new DesEngine());
}
if (mechanism == "DESEDEMAC")
{
return new CbcBlockCipherMac(new DesEdeEngine());
}
if (mechanism == "DESEDEMAC/CFB8")
{
return new CfbBlockCipherMac(new DesEdeEngine());
}
if (mechanism == "DESEDEMAC64")
{
return new CbcBlockCipherMac(new DesEdeEngine(), 64);
}
if (mechanism == "DESEDEMAC64WITHISO7816-4PADDING")
{
return new CbcBlockCipherMac(new DesEdeEngine(), 64, new ISO7816d4Padding());
}
if (mechanism == "DESWITHISO9797"
|| mechanism == "ISO9797ALG3MAC")
{
return new ISO9797Alg3Mac(new DesEngine());
}
if (mechanism == "ISO9797ALG3WITHISO7816-4PADDING")
{
return new ISO9797Alg3Mac(new DesEngine(), new ISO7816d4Padding());
}
if (mechanism == "SKIPJACKMAC")
{
return new CbcBlockCipherMac(new SkipjackEngine());
}
if (mechanism == "SKIPJACKMAC/CFB8")
{
return new CfbBlockCipherMac(new SkipjackEngine());
}
if (mechanism == "IDEAMAC")
{
return new CbcBlockCipherMac(new IdeaEngine());
}
if (mechanism == "IDEAMAC/CFB8")
{
return new CfbBlockCipherMac(new IdeaEngine());
}
if (mechanism == "RC2MAC")
{
return new CbcBlockCipherMac(new RC2Engine());
}
if (mechanism == "RC2MAC/CFB8")
{
return new CfbBlockCipherMac(new RC2Engine());
}
if (mechanism == "RC5MAC")
{
return new CbcBlockCipherMac(new RC532Engine());
}
if (mechanism == "RC5MAC/CFB8")
{
return new CfbBlockCipherMac(new RC532Engine());
}
if (mechanism == "GOST28147MAC")
{
return new Gost28147Mac();
}
if (mechanism == "VMPCMAC")
{
return new VmpcMac();
}
throw new SecurityUtilityException("Mac " + mechanism + " not recognised.");
}
public static string GetAlgorithmName(
DerObjectIdentifier oid)
{
return (string) algorithms[oid.Id];
}
public static byte[] DoFinal(
IMac mac)
{
byte[] b = new byte[mac.GetMacSize()];
mac.DoFinal(b, 0);
return b;
}
}
}

View File

@@ -0,0 +1,12 @@
using System;
namespace Org.BouncyCastle.Security
{
[Obsolete("Never thrown")]
public class NoSuchAlgorithmException : GeneralSecurityException
{
public NoSuchAlgorithmException() : base() {}
public NoSuchAlgorithmException(string message) : base(message) {}
public NoSuchAlgorithmException(string message, Exception exception) : base(message, exception) {}
}
}

View File

@@ -0,0 +1,318 @@
using System;
using System.Collections;
using System.Globalization;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Asn1.Kisa;
using Org.BouncyCastle.Asn1.Misc;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Ntt;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Security
{
public sealed class ParameterUtilities
{
private ParameterUtilities()
{
}
private static readonly Hashtable algorithms = new Hashtable();
static ParameterUtilities()
{
AddAlgorithm("AES",
"AESWRAP");
AddAlgorithm("AES128",
"2.16.840.1.101.3.4.2",
NistObjectIdentifiers.IdAes128Cbc,
NistObjectIdentifiers.IdAes128Cfb,
NistObjectIdentifiers.IdAes128Ecb,
NistObjectIdentifiers.IdAes128Ofb,
NistObjectIdentifiers.IdAes128Wrap);
AddAlgorithm("AES192",
"2.16.840.1.101.3.4.22",
NistObjectIdentifiers.IdAes192Cbc,
NistObjectIdentifiers.IdAes192Cfb,
NistObjectIdentifiers.IdAes192Ecb,
NistObjectIdentifiers.IdAes192Ofb,
NistObjectIdentifiers.IdAes192Wrap);
AddAlgorithm("AES256",
"2.16.840.1.101.3.4.42",
NistObjectIdentifiers.IdAes256Cbc,
NistObjectIdentifiers.IdAes256Cfb,
NistObjectIdentifiers.IdAes256Ecb,
NistObjectIdentifiers.IdAes256Ofb,
NistObjectIdentifiers.IdAes256Wrap);
AddAlgorithm("BLOWFISH");
AddAlgorithm("CAMELLIA",
"CAMELLIAWRAP");
AddAlgorithm("CAMELLIA128",
NttObjectIdentifiers.IdCamellia128Cbc,
NttObjectIdentifiers.IdCamellia128Wrap);
AddAlgorithm("CAMELLIA192",
NttObjectIdentifiers.IdCamellia192Cbc,
NttObjectIdentifiers.IdCamellia192Wrap);
AddAlgorithm("CAMELLIA256",
NttObjectIdentifiers.IdCamellia256Cbc,
NttObjectIdentifiers.IdCamellia256Wrap);
AddAlgorithm("CAST5",
"1.2.840.113533.7.66.10");
AddAlgorithm("CAST6");
AddAlgorithm("DES",
OiwObjectIdentifiers.DesCbc);
AddAlgorithm("DESEDE",
"DESEDEWRAP",
PkcsObjectIdentifiers.IdAlgCms3DesWrap);
AddAlgorithm("DESEDE3",
PkcsObjectIdentifiers.DesEde3Cbc);
AddAlgorithm("GOST28147",
"GOST",
"GOST-28147",
CryptoProObjectIdentifiers.GostR28147Cbc);
AddAlgorithm("HC128");
AddAlgorithm("HC256");
AddAlgorithm("IDEA",
"1.3.6.1.4.1.188.7.1.1.2");
AddAlgorithm("NOEKEON");
AddAlgorithm("RC2",
PkcsObjectIdentifiers.RC2Cbc,
PkcsObjectIdentifiers.IdAlgCmsRC2Wrap);
AddAlgorithm("RC4",
"ARC4",
"1.2.840.113549.3.4");
AddAlgorithm("RC5",
"RC5-32");
AddAlgorithm("RC5-64");
AddAlgorithm("RC6");
AddAlgorithm("RIJNDAEL");
AddAlgorithm("SALSA20");
AddAlgorithm("SEED",
KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap,
KisaObjectIdentifiers.IdSeedCbc);
AddAlgorithm("SERPENT");
AddAlgorithm("SKIPJACK");
AddAlgorithm("TEA");
AddAlgorithm("TWOFISH");
AddAlgorithm("VMPC");
AddAlgorithm("VMPC-KSA3");
AddAlgorithm("XTEA");
}
private static void AddAlgorithm(
string canonicalName,
params object[] aliases)
{
algorithms[canonicalName] = canonicalName;
foreach (object alias in aliases)
{
algorithms[alias.ToString()] = canonicalName;
}
}
public static string GetCanonicalAlgorithmName(
string algorithm)
{
return (string) algorithms[algorithm.ToUpper(CultureInfo.InvariantCulture)];
}
public static KeyParameter CreateKeyParameter(
DerObjectIdentifier algOid,
byte[] keyBytes)
{
return CreateKeyParameter(algOid.Id, keyBytes, 0, keyBytes.Length);
}
public static KeyParameter CreateKeyParameter(
string algorithm,
byte[] keyBytes)
{
return CreateKeyParameter(algorithm, keyBytes, 0, keyBytes.Length);
}
public static KeyParameter CreateKeyParameter(
DerObjectIdentifier algOid,
byte[] keyBytes,
int offset,
int length)
{
return CreateKeyParameter(algOid.Id, keyBytes, offset, length);
}
public static KeyParameter CreateKeyParameter(
string algorithm,
byte[] keyBytes,
int offset,
int length)
{
if (algorithm == null)
throw new ArgumentNullException("algorithm");
string canonical = GetCanonicalAlgorithmName(algorithm);
if (canonical == null)
throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised.");
switch (canonical)
{
case "DES":
return new DesParameters(keyBytes, offset, length);
case "DESEDE":
case "DESEDE3":
return new DesEdeParameters(keyBytes, offset, length);
case "RC2":
return new RC2Parameters(keyBytes, offset, length);
default:
return new KeyParameter(keyBytes, offset, length);
}
}
public static ICipherParameters GetCipherParameters(
DerObjectIdentifier algOid,
ICipherParameters key,
Asn1Object asn1Params)
{
return GetCipherParameters(algOid.Id, key, asn1Params);
}
public static ICipherParameters GetCipherParameters(
string algorithm,
ICipherParameters key,
Asn1Object asn1Params)
{
if (algorithm == null)
throw new ArgumentNullException("algorithm");
string canonical = GetCanonicalAlgorithmName(algorithm);
if (canonical == null)
throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised.");
byte[] iv = null;
try
{
switch (canonical)
{
case "AES":
case "AES128":
case "AES192":
case "AES256":
case "BLOWFISH":
case "CAMELLIA":
case "CAMELLIA128":
case "CAMELLIA192":
case "CAMELLIA256":
case "DES":
case "DESEDE":
case "DESEDE3":
case "NOEKEON":
case "RIJNDAEL":
case "SEED":
case "SKIPJACK":
case "TWOFISH":
iv = ((Asn1OctetString) asn1Params).GetOctets();
break;
case "RC2":
iv = RC2CbcParameter.GetInstance(asn1Params).GetIV();
break;
case "IDEA":
iv = IdeaCbcPar.GetInstance(asn1Params).GetIV();
break;
case "CAST5":
iv = Cast5CbcParameters.GetInstance(asn1Params).GetIV();
break;
}
}
catch (Exception e)
{
throw new ArgumentException("Could not process ASN.1 parameters", e);
}
if (iv != null)
{
return new ParametersWithIV(key, iv);
}
throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised.");
}
public static Asn1Encodable GenerateParameters(
DerObjectIdentifier algID,
SecureRandom random)
{
return GenerateParameters(algID.Id, random);
}
public static Asn1Encodable GenerateParameters(
string algorithm,
SecureRandom random)
{
if (algorithm == null)
throw new ArgumentNullException("algorithm");
string canonical = GetCanonicalAlgorithmName(algorithm);
if (canonical == null)
throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised.");
switch (canonical)
{
// TODO These algorithms support an IV (see GetCipherParameters)
// but JCE doesn't seem to provide an AlgorithmParametersGenerator for them
// case "BLOWFISH":
// case "RIJNDAEL":
// case "SKIPJACK":
// case "TWOFISH":
case "AES":
case "AES128":
case "AES192":
case "AES256":
return CreateIVOctetString(random, 16);
case "CAMELLIA":
case "CAMELLIA128":
case "CAMELLIA192":
case "CAMELLIA256":
return CreateIVOctetString(random, 16);
case "CAST5":
return new Cast5CbcParameters(CreateIV(random, 8), 128);
case "DES":
case "DESEDE":
case "DESEDE3":
return CreateIVOctetString(random, 8);
case "IDEA":
return new IdeaCbcPar(CreateIV(random, 8));
case "NOEKEON":
return CreateIVOctetString(random, 16);
case "RC2":
return new RC2CbcParameter(CreateIV(random, 8));
case "SEED":
return CreateIVOctetString(random, 16);
}
throw new SecurityUtilityException("Algorithm " + algorithm + " not recognised.");
}
private static Asn1OctetString CreateIVOctetString(
SecureRandom random,
int ivLength)
{
return new DerOctetString(CreateIV(random, ivLength));
}
private static byte[] CreateIV(
SecureRandom random,
int ivLength)
{
byte[] iv = new byte[ivLength];
random.NextBytes(iv);
return iv;
}
}
}

View File

@@ -0,0 +1,554 @@
using System;
using System.Collections;
using System.Globalization;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.TeleTrust;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Macs;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Paddings;
namespace Org.BouncyCastle.Security
{
/// <summary>
///
/// </summary>
public sealed class PbeUtilities
{
private PbeUtilities()
{
}
const string Pkcs5S1 = "Pkcs5S1";
const string Pkcs5S2 = "Pkcs5S2";
const string Pkcs12 = "Pkcs12";
const string OpenSsl = "OpenSsl";
private static readonly Hashtable algorithms = new Hashtable();
private static readonly Hashtable algorithmType = new Hashtable();
private static readonly Hashtable oids = new Hashtable();
static PbeUtilities()
{
algorithms["PKCS5SCHEME1"] = "Pkcs5scheme1";
algorithms["PKCS5SCHEME2"] = "Pkcs5scheme2";
algorithms["PBEWITHMD2ANDDES-CBC"] = "PBEwithMD2andDES-CBC";
algorithms[PkcsObjectIdentifiers.PbeWithMD2AndDesCbc.Id] = "PBEwithMD2andDES-CBC";
algorithms["PBEWITHMD2ANDRC2-CBC"] = "PBEwithMD2andRC2-CBC";
algorithms[PkcsObjectIdentifiers.PbeWithMD2AndRC2Cbc.Id] = "PBEwithMD2andRC2-CBC";
algorithms["PBEWITHMD5ANDDES-CBC"] = "PBEwithMD5andDES-CBC";
algorithms[PkcsObjectIdentifiers.PbeWithMD5AndDesCbc.Id] = "PBEwithMD5andDES-CBC";
algorithms["PBEWITHMD5ANDRC2-CBC"] = "PBEwithMD5andRC2-CBC";
algorithms[PkcsObjectIdentifiers.PbeWithMD5AndRC2Cbc.Id] = "PBEwithMD5andRC2-CBC";
algorithms["PBEWITHSHA1ANDDES"] = "PBEwithSHA-1andDES-CBC";
algorithms["PBEWITHSHA-1ANDDES"] = "PBEwithSHA-1andDES-CBC";
algorithms["PBEWITHSHA1ANDDES-CBC"] = "PBEwithSHA-1andDES-CBC";
algorithms["PBEWITHSHA-1ANDDES-CBC"] = "PBEwithSHA-1andDES-CBC";
algorithms[PkcsObjectIdentifiers.PbeWithSha1AndDesCbc.Id] = "PBEwithSHA-1andDES-CBC";
algorithms["PBEWITHSHA1ANDRC2"] = "PBEwithSHA-1andRC2-CBC";
algorithms["PBEWITHSHA-1ANDRC2"] = "PBEwithSHA-1andRC2-CBC";
algorithms["PBEWITHSHA1ANDRC2-CBC"] = "PBEwithSHA-1andRC2-CBC";
algorithms["PBEWITHSHA-1ANDRC2-CBC"] = "PBEwithSHA-1andRC2-CBC";
algorithms[PkcsObjectIdentifiers.PbeWithSha1AndRC2Cbc.Id] = "PBEwithSHA-1andRC2-CBC";
algorithms["PKCS12"] = "Pkcs12";
algorithms["PBEWITHSHAAND128BITRC4"] = "PBEwithSHA-1and128bitRC4";
algorithms["PBEWITHSHA1AND128BITRC4"] = "PBEwithSHA-1and128bitRC4";
algorithms["PBEWITHSHA-1AND128BITRC4"] = "PBEwithSHA-1and128bitRC4";
algorithms[PkcsObjectIdentifiers.PbeWithShaAnd128BitRC4.Id] = "PBEwithSHA-1and128bitRC4";
algorithms["PBEWITHSHAAND40BITRC4"] = "PBEwithSHA-1and40bitRC4";
algorithms["PBEWITHSHA1AND40BITRC4"] = "PBEwithSHA-1and40bitRC4";
algorithms["PBEWITHSHA-1AND40BITRC4"] = "PBEwithSHA-1and40bitRC4";
algorithms[PkcsObjectIdentifiers.PbeWithShaAnd40BitRC4.Id] = "PBEwithSHA-1and40bitRC4";
algorithms["PBEWITHSHAAND3-KEYDESEDE-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC";
algorithms["PBEWITHSHAAND3-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC";
algorithms["PBEWITHSHA1AND3-KEYDESEDE-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC";
algorithms["PBEWITHSHA1AND3-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC";
algorithms["PBEWITHSHA-1AND3-KEYDESEDE-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC";
algorithms["PBEWITHSHA-1AND3-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and3-keyDESEDE-CBC";
algorithms[PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc.Id] = "PBEwithSHA-1and3-keyDESEDE-CBC";
algorithms["PBEWITHSHAAND2-KEYDESEDE-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC";
algorithms["PBEWITHSHAAND2-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC";
algorithms["PBEWITHSHA1AND2-KEYDESEDE-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC";
algorithms["PBEWITHSHA1AND2-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC";
algorithms["PBEWITHSHA-1AND2-KEYDESEDE-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC";
algorithms["PBEWITHSHA-1AND2-KEYTRIPLEDES-CBC"] = "PBEwithSHA-1and2-keyDESEDE-CBC";
algorithms[PkcsObjectIdentifiers.PbeWithShaAnd2KeyTripleDesCbc.Id] = "PBEwithSHA-1and2-keyDESEDE-CBC";
algorithms["PBEWITHSHAAND128BITRC2-CBC"] = "PBEwithSHA-1and128bitRC2-CBC";
algorithms["PBEWITHSHA1AND128BITRC2-CBC"] = "PBEwithSHA-1and128bitRC2-CBC";
algorithms["PBEWITHSHA-1AND128BITRC2-CBC"] = "PBEwithSHA-1and128bitRC2-CBC";
algorithms[PkcsObjectIdentifiers.PbeWithShaAnd128BitRC2Cbc.Id] = "PBEwithSHA-1and128bitRC2-CBC";
algorithms["PBEWITHSHAAND40BITRC2-CBC"] = "PBEwithSHA-1and40bitRC2-CBC";
algorithms["PBEWITHSHA1AND40BITRC2-CBC"] = "PBEwithSHA-1and40bitRC2-CBC";
algorithms["PBEWITHSHA-1AND40BITRC2-CBC"] = "PBEwithSHA-1and40bitRC2-CBC";
algorithms[PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc.Id] = "PBEwithSHA-1and40bitRC2-CBC";
algorithms["PBEWITHSHAAND128BITAES-CBC-BC"] = "PBEwithSHA-1and128bitAES-CBC-BC";
algorithms["PBEWITHSHA1AND128BITAES-CBC-BC"] = "PBEwithSHA-1and128bitAES-CBC-BC";
algorithms["PBEWITHSHA-1AND128BITAES-CBC-BC"] = "PBEwithSHA-1and128bitAES-CBC-BC";
algorithms["PBEWITHSHAAND192BITAES-CBC-BC"] = "PBEwithSHA-1and192bitAES-CBC-BC";
algorithms["PBEWITHSHA1AND192BITAES-CBC-BC"] = "PBEwithSHA-1and192bitAES-CBC-BC";
algorithms["PBEWITHSHA-1AND192BITAES-CBC-BC"] = "PBEwithSHA-1and192bitAES-CBC-BC";
algorithms["PBEWITHSHAAND256BITAES-CBC-BC"] = "PBEwithSHA-1and256bitAES-CBC-BC";
algorithms["PBEWITHSHA1AND256BITAES-CBC-BC"] = "PBEwithSHA-1and256bitAES-CBC-BC";
algorithms["PBEWITHSHA-1AND256BITAES-CBC-BC"] = "PBEwithSHA-1and256bitAES-CBC-BC";
algorithms["PBEWITHSHA256AND128BITAES-CBC-BC"] = "PBEwithSHA-256and128bitAES-CBC-BC";
algorithms["PBEWITHSHA-256AND128BITAES-CBC-BC"] = "PBEwithSHA-256and128bitAES-CBC-BC";
algorithms["PBEWITHSHA256AND192BITAES-CBC-BC"] = "PBEwithSHA-256and192bitAES-CBC-BC";
algorithms["PBEWITHSHA-256AND192BITAES-CBC-BC"] = "PBEwithSHA-256and192bitAES-CBC-BC";
algorithms["PBEWITHSHA256AND256BITAES-CBC-BC"] = "PBEwithSHA-256and256bitAES-CBC-BC";
algorithms["PBEWITHSHA-256AND256BITAES-CBC-BC"] = "PBEwithSHA-256and256bitAES-CBC-BC";
algorithms["PBEWITHSHAANDIDEA"] = "PBEwithSHA-1andIDEA-CBC";
algorithms["PBEWITHSHAANDIDEA-CBC"] = "PBEwithSHA-1andIDEA-CBC";
algorithms["PBEWITHSHAANDTWOFISH"] = "PBEwithSHA-1andTWOFISH-CBC";
algorithms["PBEWITHSHAANDTWOFISH-CBC"] = "PBEwithSHA-1andTWOFISH-CBC";
algorithms["PBEWITHHMACSHA1"] = "PBEwithHmacSHA-1";
algorithms["PBEWITHHMACSHA-1"] = "PBEwithHmacSHA-1";
algorithms[OiwObjectIdentifiers.IdSha1.Id] = "PBEwithHmacSHA-1";
algorithms["PBEWITHHMACSHA224"] = "PBEwithHmacSHA-224";
algorithms["PBEWITHHMACSHA-224"] = "PBEwithHmacSHA-224";
algorithms[NistObjectIdentifiers.IdSha224.Id] = "PBEwithHmacSHA-224";
algorithms["PBEWITHHMACSHA256"] = "PBEwithHmacSHA-256";
algorithms["PBEWITHHMACSHA-256"] = "PBEwithHmacSHA-256";
algorithms[NistObjectIdentifiers.IdSha256.Id] = "PBEwithHmacSHA-256";
algorithms["PBEWITHHMACRIPEMD128"] = "PBEwithHmacRipeMD128";
algorithms[TeleTrusTObjectIdentifiers.RipeMD128.Id] = "PBEwithHmacRipeMD128";
algorithms["PBEWITHHMACRIPEMD160"] = "PBEwithHmacRipeMD160";
algorithms[TeleTrusTObjectIdentifiers.RipeMD160.Id] = "PBEwithHmacRipeMD160";
algorithms["PBEWITHHMACRIPEMD256"] = "PBEwithHmacRipeMD256";
algorithms[TeleTrusTObjectIdentifiers.RipeMD256.Id] = "PBEwithHmacRipeMD256";
algorithms["PBEWITHHMACTIGER"] = "PBEwithHmacTiger";
algorithms["PBEWITHMD5AND128BITAES-CBC-OPENSSL"] = "PBEwithMD5and128bitAES-CBC-OpenSSL";
algorithms["PBEWITHMD5AND192BITAES-CBC-OPENSSL"] = "PBEwithMD5and192bitAES-CBC-OpenSSL";
algorithms["PBEWITHMD5AND256BITAES-CBC-OPENSSL"] = "PBEwithMD5and256bitAES-CBC-OpenSSL";
algorithmType["Pkcs5scheme1"] = Pkcs5S1;
algorithmType["Pkcs5scheme2"] = Pkcs5S2;
algorithmType["PBEwithMD2andDES-CBC"] = Pkcs5S1;
algorithmType["PBEwithMD2andRC2-CBC"] = Pkcs5S1;
algorithmType["PBEwithMD5andDES-CBC"] = Pkcs5S1;
algorithmType["PBEwithMD5andRC2-CBC"] = Pkcs5S1;
algorithmType["PBEwithSHA-1andDES-CBC"] = Pkcs5S1;
algorithmType["PBEwithSHA-1andRC2-CBC"] = Pkcs5S1;
algorithmType["Pkcs12"] = Pkcs12;
algorithmType["PBEwithSHA-1and128bitRC4"] = Pkcs12;
algorithmType["PBEwithSHA-1and40bitRC4"] = Pkcs12;
algorithmType["PBEwithSHA-1and3-keyDESEDE-CBC"] = Pkcs12;
algorithmType["PBEwithSHA-1and2-keyDESEDE-CBC"] = Pkcs12;
algorithmType["PBEwithSHA-1and128bitRC2-CBC"] = Pkcs12;
algorithmType["PBEwithSHA-1and40bitRC2-CBC"] = Pkcs12;
algorithmType["PBEwithSHA-1and128bitAES-CBC-BC"] = Pkcs12;
algorithmType["PBEwithSHA-1and192bitAES-CBC-BC"] = Pkcs12;
algorithmType["PBEwithSHA-1and256bitAES-CBC-BC"] = Pkcs12;
algorithmType["PBEwithSHA-256and128bitAES-CBC-BC"] = Pkcs12;
algorithmType["PBEwithSHA-256and192bitAES-CBC-BC"] = Pkcs12;
algorithmType["PBEwithSHA-256and256bitAES-CBC-BC"] = Pkcs12;
algorithmType["PBEwithSHA-1andIDEA-CBC"] = "Pkcs12";
algorithmType["PBEwithSHA-1andTWOFISH-CBC"] = "Pkcs12";
algorithmType["PBEwithHmacSHA-1"] = Pkcs12;
algorithmType["PBEwithHmacSHA-224"] = Pkcs12;
algorithmType["PBEwithHmacSHA-256"] = Pkcs12;
algorithmType["PBEwithHmacRipeMD128"] = Pkcs12;
algorithmType["PBEwithHmacRipeMD160"] = Pkcs12;
algorithmType["PBEwithHmacRipeMD256"] = Pkcs12;
algorithmType["PBEwithHmacTiger"] = Pkcs12;
algorithmType["PBEwithMD5and128bitAES-CBC-OpenSSL"] = OpenSsl;
algorithmType["PBEwithMD5and192bitAES-CBC-OpenSSL"] = OpenSsl;
algorithmType["PBEwithMD5and256bitAES-CBC-OpenSSL"] = OpenSsl;
oids["PBEwithMD2andDES-CBC"] = PkcsObjectIdentifiers.PbeWithMD2AndDesCbc;
oids["PBEwithMD2andRC2-CBC"] = PkcsObjectIdentifiers.PbeWithMD2AndRC2Cbc;
oids["PBEwithMD5andDES-CBC"] = PkcsObjectIdentifiers.PbeWithMD5AndDesCbc;
oids["PBEwithMD5andRC2-CBC"] = PkcsObjectIdentifiers.PbeWithMD5AndRC2Cbc;
oids["PBEwithSHA-1andDES-CBC"] = PkcsObjectIdentifiers.PbeWithSha1AndDesCbc;
oids["PBEwithSHA-1andRC2-CBC"] = PkcsObjectIdentifiers.PbeWithSha1AndRC2Cbc;
oids["PBEwithSHA-1and128bitRC4"] = PkcsObjectIdentifiers.PbeWithShaAnd128BitRC4;
oids["PBEwithSHA-1and40bitRC4"] = PkcsObjectIdentifiers.PbeWithShaAnd40BitRC4;
oids["PBEwithSHA-1and3-keyDESEDE-CBC"] = PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc;
oids["PBEwithSHA-1and2-keyDESEDE-CBC"] = PkcsObjectIdentifiers.PbeWithShaAnd2KeyTripleDesCbc;
oids["PBEwithSHA-1and128bitRC2-CBC"] = PkcsObjectIdentifiers.PbeWithShaAnd128BitRC2Cbc;
oids["PBEwithSHA-1and40bitRC2-CBC"] = PkcsObjectIdentifiers.PbewithShaAnd40BitRC2Cbc;
oids["PBEwithHmacSHA-1"] = OiwObjectIdentifiers.IdSha1;
oids["PBEwithHmacSHA-224"] = NistObjectIdentifiers.IdSha224;
oids["PBEwithHmacSHA-256"] = NistObjectIdentifiers.IdSha256;
oids["PBEwithHmacRipeMD128"] = TeleTrusTObjectIdentifiers.RipeMD128;
oids["PBEwithHmacRipeMD160"] = TeleTrusTObjectIdentifiers.RipeMD160;
oids["PBEwithHmacRipeMD256"] = TeleTrusTObjectIdentifiers.RipeMD256;
}
static PbeParametersGenerator MakePbeGenerator(
string type,
IDigest digest,
byte[] key,
byte[] salt,
int iterationCount)
{
PbeParametersGenerator generator;
if (type.Equals(Pkcs5S1))
{
generator = new Pkcs5S1ParametersGenerator(digest);
}
else if (type.Equals(Pkcs5S2))
{
generator = new Pkcs5S2ParametersGenerator();
}
else if (type.Equals(Pkcs12))
{
generator = new Pkcs12ParametersGenerator(digest);
}
else if (type.Equals(OpenSsl))
{
generator = new OpenSslPbeParametersGenerator();
}
else
{
throw new ArgumentException("Unknown PBE type: " + type, "type");
}
generator.Init(key, salt, iterationCount);
return generator;
}
/// <summary>
/// Returns a ObjectIdentifier for a give encoding.
/// </summary>
/// <param name="mechanism">A string representation of the encoding.</param>
/// <returns>A DerObjectIdentifier, null if the Oid is not available.</returns>
public static DerObjectIdentifier GetObjectIdentifier(
string mechanism)
{
mechanism = (string) algorithms[mechanism.ToUpper(CultureInfo.InvariantCulture)];
if (mechanism != null)
{
return (DerObjectIdentifier)oids[mechanism];
}
return null;
}
public static ICollection Algorithms
{
get { return oids.Keys; }
}
public static bool IsPkcs12(
string algorithm)
{
string mechanism = (string) algorithms[algorithm.ToUpper(CultureInfo.InvariantCulture)];
return mechanism != null && Pkcs12.Equals(algorithmType[mechanism]);
}
public static bool IsPkcs5Scheme1(
string algorithm)
{
string mechanism = (string)algorithms[algorithm.ToUpper(CultureInfo.InvariantCulture)];
return mechanism != null && Pkcs5S1.Equals(algorithmType[mechanism]);
}
public static bool IsPkcs5Scheme2(
string algorithm)
{
string mechanism = (string)algorithms[algorithm.ToUpper(CultureInfo.InvariantCulture)];
return mechanism != null && Pkcs5S2.Equals(algorithmType[mechanism]);
}
public static bool IsOpenSsl(
string algorithm)
{
string mechanism = (string)algorithms[algorithm.ToUpper(CultureInfo.InvariantCulture)];
return mechanism != null && OpenSsl.Equals(algorithmType[mechanism]);
}
public static bool IsPbeAlgorithm(
string algorithm)
{
string mechanism = (string)algorithms[algorithm.ToUpper(CultureInfo.InvariantCulture)];
return mechanism != null && algorithmType[mechanism] != null;
}
public static Asn1Encodable GenerateAlgorithmParameters(
DerObjectIdentifier algorithmOid,
byte[] salt,
int iterationCount)
{
return GenerateAlgorithmParameters(algorithmOid.Id, salt, iterationCount);
}
public static Asn1Encodable GenerateAlgorithmParameters(
string algorithm,
byte[] salt,
int iterationCount)
{
if (IsPkcs12(algorithm))
{
return new Pkcs12PbeParams(salt, iterationCount);
}
else if (IsPkcs5Scheme2(algorithm))
{
return new Pbkdf2Params(salt, iterationCount);
}
else
{
return new PbeParameter(salt, iterationCount);
}
}
public static ICipherParameters GenerateCipherParameters(
DerObjectIdentifier algorithmOid,
char[] password,
Asn1Encodable pbeParameters)
{
return GenerateCipherParameters(algorithmOid.Id, password, false, pbeParameters);
}
public static ICipherParameters GenerateCipherParameters(
DerObjectIdentifier algorithmOid,
char[] password,
bool wrongPkcs12Zero,
Asn1Encodable pbeParameters)
{
return GenerateCipherParameters(algorithmOid.Id, password, wrongPkcs12Zero, pbeParameters);
}
public static ICipherParameters GenerateCipherParameters(
string algorithm,
char[] password,
Asn1Encodable pbeParameters)
{
return GenerateCipherParameters(algorithm, password, false, pbeParameters);
}
public static ICipherParameters GenerateCipherParameters(
string algorithm,
char[] password,
bool wrongPkcs12Zero,
Asn1Encodable pbeParameters)
{
string mechanism = (string) algorithms[algorithm.ToUpper(CultureInfo.InvariantCulture)];
byte[] keyBytes;
//string type = (string)algorithmType[mechanism];
byte[] salt;
int iterationCount;
if (IsPkcs12(mechanism))
{
Pkcs12PbeParams pbeParams = Pkcs12PbeParams.GetInstance(pbeParameters);
salt = pbeParams.GetIV();
iterationCount = pbeParams.Iterations.IntValue;
keyBytes = PbeParametersGenerator.Pkcs12PasswordToBytes(password, wrongPkcs12Zero);
}
else if (IsPkcs5Scheme2(mechanism))
{
Pbkdf2Params pbeParams = Pbkdf2Params.GetInstance(pbeParameters);
salt = pbeParams.GetSalt();
iterationCount = pbeParams.IterationCount.IntValue;
keyBytes = PbeParametersGenerator.Pkcs5PasswordToBytes(password);
}
else
{
PbeParameter pbeParams = PbeParameter.GetInstance(pbeParameters);
salt = pbeParams.GetSalt();
iterationCount = pbeParams.IterationCount.IntValue;
keyBytes = PbeParametersGenerator.Pkcs5PasswordToBytes(password);
}
ICipherParameters parameters = null;
if (mechanism.StartsWith("PBEwithSHA-1"))
{
PbeParametersGenerator generator = MakePbeGenerator(
(string) algorithmType[mechanism], new Sha1Digest(), keyBytes, salt, iterationCount);
if (mechanism.Equals("PBEwithSHA-1and128bitRC4"))
{
parameters = generator.GenerateDerivedParameters("RC4", 128);
}
else if (mechanism.Equals("PBEwithSHA-1and40bitRC4"))
{
parameters = generator.GenerateDerivedParameters("RC4", 40);
}
else if (mechanism.Equals("PBEwithSHA-1and3-keyDESEDE-CBC"))
{
parameters = generator.GenerateDerivedParameters("DESEDE", 192, 64);
}
else if (mechanism.Equals("PBEwithSHA-1and2-keyDESEDE-CBC"))
{
parameters = generator.GenerateDerivedParameters("DESEDE", 128, 64);
}
else if (mechanism.Equals("PBEwithSHA-1and128bitRC2-CBC"))
{
parameters = generator.GenerateDerivedParameters("RC2", 128, 64);
}
else if (mechanism.Equals("PBEwithSHA-1and40bitRC2-CBC"))
{
parameters = generator.GenerateDerivedParameters("RC2", 40, 64);
}
else if (mechanism.Equals("PBEwithSHA-1andDES-CBC"))
{
parameters = generator.GenerateDerivedParameters("DES", 64, 64);
}
else if (mechanism.Equals("PBEwithSHA-1andRC2-CBC"))
{
parameters = generator.GenerateDerivedParameters("RC2", 64, 64);
}
else if (mechanism.Equals("PBEwithSHA-1and128bitAES-CBC-BC"))
{
parameters = generator.GenerateDerivedParameters("AES", 128, 128);
}
else if (mechanism.Equals("PBEwithSHA-1and192bitAES-CBC-BC"))
{
parameters = generator.GenerateDerivedParameters("AES", 192, 128);
}
else if (mechanism.Equals("PBEwithSHA-1and256bitAES-CBC-BC"))
{
parameters = generator.GenerateDerivedParameters("AES", 256, 128);
}
}
else if (mechanism.StartsWith("PBEwithSHA-256"))
{
PbeParametersGenerator generator = MakePbeGenerator(
(string) algorithmType[mechanism], new Sha256Digest(), keyBytes, salt, iterationCount);
if (mechanism.Equals("PBEwithSHA-256and128bitAES-CBC-BC"))
{
parameters = generator.GenerateDerivedParameters("AES", 128, 128);
}
else if (mechanism.Equals("PBEwithSHA-256and192bitAES-CBC-BC"))
{
parameters = generator.GenerateDerivedParameters("AES", 192, 128);
}
else if (mechanism.Equals("PBEwithSHA-256and256bitAES-CBC-BC"))
{
parameters = generator.GenerateDerivedParameters("AES", 256, 128);
}
}
else if (mechanism.StartsWith("PBEwithMD5"))
{
PbeParametersGenerator generator = MakePbeGenerator(
(string)algorithmType[mechanism], new MD5Digest(), keyBytes, salt, iterationCount);
if (mechanism.Equals("PBEwithMD5andDES-CBC"))
{
parameters = generator.GenerateDerivedParameters("DES", 64, 64);
}
else if (mechanism.Equals("PBEwithMD5andRC2-CBC"))
{
parameters = generator.GenerateDerivedParameters("RC2", 64, 64);
}
else if (mechanism.Equals("PBEwithMD5and128bitAES-CBC-OpenSSL"))
{
parameters = generator.GenerateDerivedParameters("AES", 128, 128);
}
else if (mechanism.Equals("PBEwithMD5and192bitAES-CBC-OpenSSL"))
{
parameters = generator.GenerateDerivedParameters("AES", 192, 128);
}
else if (mechanism.Equals("PBEwithMD5and256bitAES-CBC-OpenSSL"))
{
parameters = generator.GenerateDerivedParameters("AES", 256, 128);
}
}
else if (mechanism.StartsWith("PBEwithMD2"))
{
PbeParametersGenerator generator = MakePbeGenerator(
(string)algorithmType[mechanism], new MD2Digest(), keyBytes, salt, iterationCount);
if (mechanism.Equals("PBEwithMD2andDES-CBC"))
{
parameters = generator.GenerateDerivedParameters("DES", 64, 64);
}
else if (mechanism.Equals("PBEwithMD2andRC2-CBC"))
{
parameters = generator.GenerateDerivedParameters("RC2", 64, 64);
}
}
else if (mechanism.StartsWith("PBEwithHmac"))
{
string digestName = mechanism.Substring("PBEwithHmac".Length);
IDigest digest = DigestUtilities.GetDigest(digestName);
PbeParametersGenerator generator = MakePbeGenerator(
(string) algorithmType[mechanism], digest, keyBytes, salt, iterationCount);
int bitLen = digest.GetDigestSize() * 8;
parameters = generator.GenerateDerivedMacParameters(bitLen);
}
Array.Clear(keyBytes, 0, keyBytes.Length);
return parameters;
}
public static object CreateEngine(
DerObjectIdentifier algorithmOid)
{
return CreateEngine(algorithmOid.Id);
}
private static bool EndsWith(
string s,
string ending)
{
int pos = s.Length - ending.Length;
return pos >= 0 && s.Substring(pos) == ending;
}
public static object CreateEngine(
string algorithm)
{
string mechanism = (string)algorithms[algorithm.ToUpper(CultureInfo.InvariantCulture)];
if (mechanism.StartsWith("PBEwithHmac"))
{
string digestName = mechanism.Substring("PBEwithHmac".Length);
return MacUtilities.GetMac("HMAC/" + digestName);
}
if (mechanism.StartsWith("PBEwithMD2")
|| mechanism.StartsWith("PBEwithMD5")
|| mechanism.StartsWith("PBEwithSHA-1"))
{
if (EndsWith(mechanism, "RC2-CBC"))
{
return CipherUtilities.GetCipher("RC2/CBC");
}
if (EndsWith(mechanism, "RC4"))
{
return CipherUtilities.GetCipher("RC4");
}
if (EndsWith(mechanism, "DES-CBC"))
{
return CipherUtilities.GetCipher("DES/CBC");
}
if (EndsWith(mechanism, "DESEDE-CBC"))
{
return CipherUtilities.GetCipher("DESEDE/CBC");
}
}
return null;
}
public static string GetEncodingName(
DerObjectIdentifier oid)
{
return (string) algorithms[oid.Id];
}
}
}

View File

@@ -0,0 +1,177 @@
using System;
using System.Collections;
using System.IO;
using System.Text;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.Sec;
using Org.BouncyCastle.Asn1.TeleTrust;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
namespace Org.BouncyCastle.Security
{
public sealed class PrivateKeyFactory
{
private PrivateKeyFactory()
{
}
public static AsymmetricKeyParameter CreateKey(
byte[] privateKeyInfoData)
{
return CreateKey(
PrivateKeyInfo.GetInstance(
Asn1Object.FromByteArray(privateKeyInfoData)));
}
public static AsymmetricKeyParameter CreateKey(
Stream inStr)
{
return CreateKey(
PrivateKeyInfo.GetInstance(
Asn1Object.FromStream(inStr)));
}
public static AsymmetricKeyParameter CreateKey(
PrivateKeyInfo keyInfo)
{
AlgorithmIdentifier algID = keyInfo.AlgorithmID;
DerObjectIdentifier algOid = algID.ObjectID;
if (algOid.Equals(PkcsObjectIdentifiers.RsaEncryption))
{
RsaPrivateKeyStructure keyStructure = new RsaPrivateKeyStructure(
Asn1Sequence.GetInstance(keyInfo.PrivateKey));
return new RsaPrivateCrtKeyParameters(
keyStructure.Modulus,
keyStructure.PublicExponent,
keyStructure.PrivateExponent,
keyStructure.Prime1,
keyStructure.Prime2,
keyStructure.Exponent1,
keyStructure.Exponent2,
keyStructure.Coefficient);
}
else if (algOid.Equals(PkcsObjectIdentifiers.DhKeyAgreement))
{
DHParameter para = new DHParameter(
Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
DerInteger derX = (DerInteger)keyInfo.PrivateKey;
return new DHPrivateKeyParameters(
derX.Value,
new DHParameters(para.P, para.G));
}
else if (algOid.Equals(OiwObjectIdentifiers.ElGamalAlgorithm))
{
ElGamalParameter para = new ElGamalParameter(
Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
DerInteger derX = (DerInteger)keyInfo.PrivateKey;
return new ElGamalPrivateKeyParameters(
derX.Value,
new ElGamalParameters(para.P, para.G));
}
else if (algOid.Equals(X9ObjectIdentifiers.IdDsa))
{
DsaParameter para = DsaParameter.GetInstance(
algID.Parameters.ToAsn1Object());
DerInteger derX = (DerInteger) keyInfo.PrivateKey;
return new DsaPrivateKeyParameters(
derX.Value,
new DsaParameters(para.P, para.Q, para.G));
}
else if (algOid.Equals(X9ObjectIdentifiers.IdECPublicKey))
{
X962Parameters para = new X962Parameters(algID.Parameters.ToAsn1Object());
X9ECParameters ecP;
if (para.IsNamedCurve)
{
// TODO ECGost3410NamedCurves support (returns ECDomainParameters though)
DerObjectIdentifier oid = (DerObjectIdentifier) para.Parameters;
ecP = X962NamedCurves.GetByOid(oid);
if (ecP == null)
{
ecP = SecNamedCurves.GetByOid(oid);
if (ecP == null)
{
ecP = NistNamedCurves.GetByOid(oid);
if (ecP == null)
{
ecP = TeleTrusTNamedCurves.GetByOid(oid);
}
}
}
}
else
{
ecP = new X9ECParameters((Asn1Sequence) para.Parameters);
}
ECDomainParameters dParams = new ECDomainParameters(
ecP.Curve,
ecP.G,
ecP.N,
ecP.H,
ecP.GetSeed());
ECPrivateKeyStructure ec = new ECPrivateKeyStructure(
Asn1Sequence.GetInstance(keyInfo.PrivateKey));
return new ECPrivateKeyParameters(ec.GetKey(), dParams);
}
else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x2001))
{
Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters(
Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
ECPrivateKeyStructure ec = new ECPrivateKeyStructure(
Asn1Sequence.GetInstance(keyInfo.PrivateKey));
ECDomainParameters ecP = ECGost3410NamedCurves.GetByOid(gostParams.PublicKeyParamSet);
if (ecP == null)
return null;
return new ECPrivateKeyParameters(ec.GetKey(), gostParams.PublicKeyParamSet);
}
else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x94))
{
Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters(
Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
DerOctetString derX = (DerOctetString) keyInfo.PrivateKey;
byte[] keyEnc = derX.GetOctets();
byte[] keyBytes = new byte[keyEnc.Length];
for (int i = 0; i != keyEnc.Length; i++)
{
keyBytes[i] = keyEnc[keyEnc.Length - 1 - i]; // was little endian
}
BigInteger x = new BigInteger(1, keyBytes);
return new Gost3410PrivateKeyParameters(x, gostParams.PublicKeyParamSet);
}
else
{
throw new SecurityUtilityException("algorithm identifier in key not recognised");
}
}
}
}

View File

@@ -0,0 +1,210 @@
using System;
using System.Collections;
using System.IO;
using System.Text;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Oiw;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.Sec;
using Org.BouncyCastle.Asn1.TeleTrust;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
namespace Org.BouncyCastle.Security
{
public sealed class PublicKeyFactory
{
private PublicKeyFactory()
{
}
public static AsymmetricKeyParameter CreateKey(
byte[] keyInfoData)
{
return CreateKey(
SubjectPublicKeyInfo.GetInstance(
Asn1Object.FromByteArray(keyInfoData)));
}
public static AsymmetricKeyParameter CreateKey(
Stream inStr)
{
return CreateKey(
SubjectPublicKeyInfo.GetInstance(
Asn1Object.FromStream(inStr)));
}
public static AsymmetricKeyParameter CreateKey(
SubjectPublicKeyInfo keyInfo)
{
AlgorithmIdentifier algID = keyInfo.AlgorithmID;
DerObjectIdentifier algOid = algID.ObjectID;
if (algOid.Equals(PkcsObjectIdentifiers.RsaEncryption)
|| algOid.Equals(X509ObjectIdentifiers.IdEARsa))
{
RsaPublicKeyStructure pubKey = RsaPublicKeyStructure.GetInstance(
keyInfo.GetPublicKey());
return new RsaKeyParameters(false, pubKey.Modulus, pubKey.PublicExponent);
}
else if (algOid.Equals(PkcsObjectIdentifiers.DhKeyAgreement)
|| algOid.Equals(X9ObjectIdentifiers.DHPublicNumber))
{
DHParameter para = new DHParameter(
Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
DerInteger derY = (DerInteger) keyInfo.GetPublicKey();
return new DHPublicKeyParameters(derY.Value, new DHParameters(para.P, para.G));
}
else if (algOid.Equals(OiwObjectIdentifiers.ElGamalAlgorithm))
{
ElGamalParameter para = new ElGamalParameter(
Asn1Sequence.GetInstance(algID.Parameters.ToAsn1Object()));
DerInteger derY = (DerInteger) keyInfo.GetPublicKey();
return new ElGamalPublicKeyParameters(
derY.Value,
new ElGamalParameters(para.P, para.G));
}
else if (algOid.Equals(X9ObjectIdentifiers.IdDsa)
|| algOid.Equals(OiwObjectIdentifiers.DsaWithSha1))
{
DerInteger derY = (DerInteger) keyInfo.GetPublicKey();
Asn1Encodable ae = algID.Parameters;
Asn1Object ao = ae == null ? null : ae.ToAsn1Object();
DsaParameter para = DsaParameter.GetInstance(ao);
return new DsaPublicKeyParameters(
derY.Value,
new DsaParameters(para.P, para.Q, para.G));
}
else if (algOid.Equals(X9ObjectIdentifiers.IdECPublicKey))
{
X962Parameters para = new X962Parameters(
algID.Parameters.ToAsn1Object());
X9ECParameters ecP;
if (para.IsNamedCurve)
{
// TODO ECGost3410NamedCurves support (returns ECDomainParameters though)
DerObjectIdentifier oid = (DerObjectIdentifier)para.Parameters;
ecP = X962NamedCurves.GetByOid(oid);
if (ecP == null)
{
ecP = SecNamedCurves.GetByOid(oid);
if (ecP == null)
{
ecP = NistNamedCurves.GetByOid(oid);
if (ecP == null)
{
ecP = TeleTrusTNamedCurves.GetByOid(oid);
}
}
}
}
else
{
ecP = new X9ECParameters((Asn1Sequence)para.Parameters.ToAsn1Object());
}
ECDomainParameters dParams = new ECDomainParameters(
ecP.Curve,
ecP.G,
ecP.N,
ecP.H,
ecP.GetSeed());
DerBitString bits = keyInfo.PublicKeyData;
byte[] data = bits.GetBytes();
Asn1OctetString key = new DerOctetString(data);
X9ECPoint derQ = new X9ECPoint(dParams.Curve, key);
return new ECPublicKeyParameters(derQ.Point, dParams);
}
else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x2001))
{
Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters(
(Asn1Sequence) algID.Parameters);
Asn1OctetString key;
try
{
key = (Asn1OctetString) keyInfo.GetPublicKey();
}
catch (IOException)
{
throw new ArgumentException("invalid info structure in GOST3410 public key");
}
byte[] keyEnc = key.GetOctets();
byte[] x = new byte[32];
byte[] y = new byte[32];
for (int i = 0; i != y.Length; i++)
{
x[i] = keyEnc[32 - 1 - i];
}
for (int i = 0; i != x.Length; i++)
{
y[i] = keyEnc[64 - 1 - i];
}
ECDomainParameters ecP = ECGost3410NamedCurves.GetByOid(gostParams.PublicKeyParamSet);
if (ecP == null)
return null;
ECPoint q = ecP.Curve.CreatePoint(new BigInteger(1, x), new BigInteger(1, y), false);
return new ECPublicKeyParameters(q, gostParams.PublicKeyParamSet);
}
else if (algOid.Equals(CryptoProObjectIdentifiers.GostR3410x94))
{
Gost3410PublicKeyAlgParameters algParams = new Gost3410PublicKeyAlgParameters(
(Asn1Sequence) algID.Parameters);
DerOctetString derY;
try
{
derY = (DerOctetString) keyInfo.GetPublicKey();
}
catch (IOException)
{
throw new ArgumentException("invalid info structure in GOST3410 public key");
}
byte[] keyEnc = derY.GetOctets();
byte[] keyBytes = new byte[keyEnc.Length];
for (int i = 0; i != keyEnc.Length; i++)
{
keyBytes[i] = keyEnc[keyEnc.Length - 1 - i]; // was little endian
}
BigInteger y = new BigInteger(1, keyBytes);
return new Gost3410PublicKeyParameters(y, algParams.PublicKeyParamSet);
}
else
{
throw new SecurityUtilityException("algorithm identifier in key not recognised: " + algOid);
}
}
}
}

View File

@@ -0,0 +1,224 @@
using System;
using System.Globalization;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Prng;
namespace Org.BouncyCastle.Security
{
public class SecureRandom
: Random
{
private static readonly SecureRandom[] master = { null };
private static SecureRandom Master
{
get
{
if (master[0] == null)
{
IRandomGenerator gen = new DigestRandomGenerator(new Sha256Digest());
gen = new ReversedWindowGenerator(gen, 32);
SecureRandom sr = master[0] = new SecureRandom(gen);
sr.SetSeed(DateTime.Now.Ticks);
sr.SetSeed(new ThreadedSeedGenerator().GenerateSeed(24, true));
sr.GenerateSeed(1 + sr.Next(32));
}
return master[0];
}
}
public static SecureRandom GetInstance(
string algorithm)
{
// TODO Compared to JDK, we don't auto-seed if the client forgets - problem?
// TODO Support all digests more generally, by stripping PRNG and calling DigestUtilities?
IDigest digest = null;
switch (algorithm.ToUpper(CultureInfo.InvariantCulture))
{
case "SHA1PRNG":
digest = new Sha1Digest();
break;
case "SHA256PRNG":
digest = new Sha256Digest();
break;
}
if (digest != null)
{
return new SecureRandom(new DigestRandomGenerator(digest));
}
throw new ArgumentException("Unrecognised PRNG algorithm: " + algorithm, "algorithm");
}
public static byte[] GetSeed(
int length)
{
return Master.GenerateSeed(length);
}
protected IRandomGenerator generator;
public SecureRandom()
: base(0)
{
this.generator = new DigestRandomGenerator(new Sha1Digest());
SetSeed(GetSeed(8));
}
public SecureRandom(
byte[] inSeed)
: base(0)
{
this.generator = new DigestRandomGenerator(new Sha1Digest());
SetSeed(inSeed);
}
/// <summary>Use the specified instance of IRandomGenerator as random source.</summary>
/// <remarks>
/// This constructor performs no seeding of either the <c>IRandomGenerator</c> or the
/// constructed <c>SecureRandom</c>. It is the responsibility of the client to provide
/// proper seed material as necessary/appropriate for the given <c>IRandomGenerator</c>
/// implementation.
/// </remarks>
/// <param name="generator">The source to generate all random bytes from.</param>
public SecureRandom(
IRandomGenerator generator)
: base(0)
{
this.generator = generator;
}
public virtual byte[] GenerateSeed(
int length)
{
SetSeed(DateTime.Now.Ticks);
byte[] rv = new byte[length];
NextBytes(rv);
return rv;
}
public virtual void SetSeed(
byte[] inSeed)
{
generator.AddSeedMaterial(inSeed);
}
public virtual void SetSeed(
long seed)
{
generator.AddSeedMaterial(seed);
}
public override int Next()
{
for (;;)
{
int i = NextInt() & int.MaxValue;
if (i != int.MaxValue)
return i;
}
}
public override int Next(
int maxValue)
{
if (maxValue < 2)
{
if (maxValue < 0)
throw new ArgumentOutOfRangeException("maxValue < 0");
return 0;
}
// Test whether maxValue is a power of 2
if ((maxValue & -maxValue) == maxValue)
{
int val = NextInt() & int.MaxValue;
long lr = ((long) maxValue * (long) val) >> 31;
return (int) lr;
}
int bits, result;
do
{
bits = NextInt() & int.MaxValue;
result = bits % maxValue;
}
while (bits - result + (maxValue - 1) < 0); // Ignore results near overflow
return result;
}
public override int Next(
int minValue,
int maxValue)
{
if (maxValue <= minValue)
{
if (maxValue == minValue)
return minValue;
throw new ArgumentException("maxValue cannot be less than minValue");
}
int diff = maxValue - minValue;
if (diff > 0)
return minValue + Next(diff);
for (;;)
{
int i = NextInt();
if (i >= minValue && i < maxValue)
return i;
}
}
public override void NextBytes(
byte[] buffer)
{
generator.NextBytes(buffer);
}
public virtual void NextBytes(
byte[] buffer,
int start,
int length)
{
generator.NextBytes(buffer, start, length);
}
private static readonly double DoubleScale = System.Math.Pow(2.0, 64.0);
public override double NextDouble()
{
return Convert.ToDouble((ulong) NextLong()) / DoubleScale;
}
public virtual int NextInt()
{
byte[] intBytes = new byte[4];
NextBytes(intBytes);
int result = 0;
for (int i = 0; i < 4; i++)
{
result = (result << 8) + (intBytes[i] & 0xff);
}
return result;
}
public virtual long NextLong()
{
return ((long)(uint) NextInt() << 32) | (long)(uint) NextInt();
}
}
}

View File

@@ -0,0 +1,33 @@
using System;
namespace Org.BouncyCastle.Security
{
public class SecurityUtilityException
: Exception
{
/**
* base constructor.
*/
public SecurityUtilityException()
{
}
/**
* create a SecurityUtilityException with the given message.
*
* @param message the message to be carried with the exception.
*/
public SecurityUtilityException(
string message)
: base(message)
{
}
public SecurityUtilityException(
string message,
Exception exception)
: base(message, exception)
{
}
}
}

View File

@@ -0,0 +1,11 @@
using System;
namespace Org.BouncyCastle.Security
{
public class SignatureException : GeneralSecurityException
{
public SignatureException() : base() { }
public SignatureException(string message) : base(message) { }
public SignatureException(string message, Exception exception) : base(message, exception) { }
}
}

View File

@@ -0,0 +1,517 @@
using System;
using System.Collections;
using System.Globalization;
using System.IO;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.CryptoPro;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.TeleTrust;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Signers;
namespace Org.BouncyCastle.Security
{
/// <summary>
/// Signer Utility class contains methods that can not be specifically grouped into other classes.
/// </summary>
public sealed class SignerUtilities
{
private SignerUtilities()
{
}
internal static readonly Hashtable algorithms = new Hashtable();
internal static readonly Hashtable oids = new Hashtable();
static SignerUtilities()
{
algorithms["MD2WITHRSA"] = "MD2withRSA";
algorithms["MD2WITHRSAENCRYPTION"] = "MD2withRSA";
algorithms[PkcsObjectIdentifiers.MD2WithRsaEncryption.Id] = "MD2withRSA";
algorithms["MD4WITHRSA"] = "MD4withRSA";
algorithms["MD4WITHRSAENCRYPTION"] = "MD4withRSA";
algorithms[PkcsObjectIdentifiers.MD4WithRsaEncryption.Id] = "MD4withRSA";
algorithms["MD5WITHRSA"] = "MD5withRSA";
algorithms["MD5WITHRSAENCRYPTION"] = "MD5withRSA";
algorithms[PkcsObjectIdentifiers.MD5WithRsaEncryption.Id] = "MD5withRSA";
algorithms["SHA1WITHRSA"] = "SHA-1withRSA";
algorithms["SHA1WITHRSAENCRYPTION"] = "SHA-1withRSA";
algorithms[PkcsObjectIdentifiers.Sha1WithRsaEncryption.Id] = "SHA-1withRSA";
algorithms["SHA-1WITHRSA"] = "SHA-1withRSA";
algorithms["SHA224WITHRSA"] = "SHA-224withRSA";
algorithms["SHA224WITHRSAENCRYPTION"] = "SHA-224withRSA";
algorithms[PkcsObjectIdentifiers.Sha224WithRsaEncryption.Id] = "SHA-224withRSA";
algorithms["SHA-224WITHRSA"] = "SHA-224withRSA";
algorithms["SHA256WITHRSA"] = "SHA-256withRSA";
algorithms["SHA256WITHRSAENCRYPTION"] = "SHA-256withRSA";
algorithms[PkcsObjectIdentifiers.Sha256WithRsaEncryption.Id] = "SHA-256withRSA";
algorithms["SHA-256WITHRSA"] = "SHA-256withRSA";
algorithms["SHA384WITHRSA"] = "SHA-384withRSA";
algorithms["SHA384WITHRSAENCRYPTION"] = "SHA-384withRSA";
algorithms[PkcsObjectIdentifiers.Sha384WithRsaEncryption.Id] = "SHA-384withRSA";
algorithms["SHA-384WITHRSA"] = "SHA-384withRSA";
algorithms["SHA512WITHRSA"] = "SHA-512withRSA";
algorithms["SHA512WITHRSAENCRYPTION"] = "SHA-512withRSA";
algorithms[PkcsObjectIdentifiers.Sha512WithRsaEncryption.Id] = "SHA-512withRSA";
algorithms["SHA-512WITHRSA"] = "SHA-512withRSA";
algorithms["PSSWITHRSA"] = "PSSwithRSA";
algorithms["RSASSA-PSS"] = "PSSwithRSA";
algorithms[PkcsObjectIdentifiers.IdRsassaPss.Id] = "PSSwithRSA";
algorithms["SHA1WITHRSAANDMGF1"] = "SHA-1withRSAandMGF1";
algorithms["SHA-1WITHRSAANDMGF1"] = "SHA-1withRSAandMGF1";
algorithms["SHA1WITHRSA/PSS"] = "SHA-1withRSAandMGF1";
algorithms["SHA-1WITHRSA/PSS"] = "SHA-1withRSAandMGF1";
algorithms["SHA224WITHRSAANDMGF1"] = "SHA-224withRSAandMGF1";
algorithms["SHA-224WITHRSAANDMGF1"] = "SHA-224withRSAandMGF1";
algorithms["SHA224WITHRSA/PSS"] = "SHA-224withRSAandMGF1";
algorithms["SHA-224WITHRSA/PSS"] = "SHA-224withRSAandMGF1";
algorithms["SHA256WITHRSAANDMGF1"] = "SHA-256withRSAandMGF1";
algorithms["SHA-256WITHRSAANDMGF1"] = "SHA-256withRSAandMGF1";
algorithms["SHA256WITHRSA/PSS"] = "SHA-256withRSAandMGF1";
algorithms["SHA-256WITHRSA/PSS"] = "SHA-256withRSAandMGF1";
algorithms["SHA384WITHRSAANDMGF1"] = "SHA-384withRSAandMGF1";
algorithms["SHA-384WITHRSAANDMGF1"] = "SHA-384withRSAandMGF1";
algorithms["SHA384WITHRSA/PSS"] = "SHA-384withRSAandMGF1";
algorithms["SHA-384WITHRSA/PSS"] = "SHA-384withRSAandMGF1";
algorithms["SHA512WITHRSAANDMGF1"] = "SHA-512withRSAandMGF1";
algorithms["SHA-512WITHRSAANDMGF1"] = "SHA-512withRSAandMGF1";
algorithms["SHA512WITHRSA/PSS"] = "SHA-512withRSAandMGF1";
algorithms["SHA-512WITHRSA/PSS"] = "SHA-512withRSAandMGF1";
algorithms["RIPEMD128WITHRSA"] = "RIPEMD128withRSA";
algorithms["RIPEMD128WITHRSAENCRYPTION"] = "RIPEMD128withRSA";
algorithms[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128.Id] = "RIPEMD128withRSA";
algorithms["RIPEMD160WITHRSA"] = "RIPEMD160withRSA";
algorithms["RIPEMD160WITHRSAENCRYPTION"] = "RIPEMD160withRSA";
algorithms[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160.Id] = "RIPEMD160withRSA";
algorithms["RIPEMD256WITHRSA"] = "RIPEMD256withRSA";
algorithms["RIPEMD256WITHRSAENCRYPTION"] = "RIPEMD256withRSA";
algorithms[TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256.Id] = "RIPEMD256withRSA";
algorithms["NONEWITHDSA"] = "NONEwithDSA";
algorithms["DSAWITHNONE"] = "NONEwithDSA";
algorithms["DSA"] = "SHA-1withDSA";
algorithms["DSAWITHSHA1"] = "SHA-1withDSA";
algorithms["DSAWITHSHA-1"] = "SHA-1withDSA";
algorithms["SHA/DSA"] = "SHA-1withDSA";
algorithms["SHA1/DSA"] = "SHA-1withDSA";
algorithms["SHA-1/DSA"] = "SHA-1withDSA";
algorithms["SHA1WITHDSA"] = "SHA-1withDSA";
algorithms["SHA-1WITHDSA"] = "SHA-1withDSA";
algorithms[X9ObjectIdentifiers.IdDsaWithSha1.Id] = "SHA-1withDSA";
algorithms["DSAWITHSHA224"] = "SHA-224withDSA";
algorithms["DSAWITHSHA-224"] = "SHA-224withDSA";
algorithms["SHA224/DSA"] = "SHA-224withDSA";
algorithms["SHA-224/DSA"] = "SHA-224withDSA";
algorithms["SHA224WITHDSA"] = "SHA-224withDSA";
algorithms["SHA-224WITHDSA"] = "SHA-224withDSA";
algorithms[NistObjectIdentifiers.DsaWithSha224.Id] = "SHA-224withDSA";
algorithms["DSAWITHSHA256"] = "SHA-256withDSA";
algorithms["DSAWITHSHA-256"] = "SHA-256withDSA";
algorithms["SHA256/DSA"] = "SHA-256withDSA";
algorithms["SHA-256/DSA"] = "SHA-256withDSA";
algorithms["SHA256WITHDSA"] = "SHA-256withDSA";
algorithms["SHA-256WITHDSA"] = "SHA-256withDSA";
algorithms[NistObjectIdentifiers.DsaWithSha256.Id] = "SHA-256withDSA";
algorithms["DSAWITHSHA384"] = "SHA-384withDSA";
algorithms["DSAWITHSHA-384"] = "SHA-384withDSA";
algorithms["SHA384/DSA"] = "SHA-384withDSA";
algorithms["SHA-384/DSA"] = "SHA-384withDSA";
algorithms["SHA384WITHDSA"] = "SHA-384withDSA";
algorithms["SHA-384WITHDSA"] = "SHA-384withDSA";
algorithms[NistObjectIdentifiers.DsaWithSha384.Id] = "SHA-384withDSA";
algorithms["DSAWITHSHA512"] = "SHA-512withDSA";
algorithms["DSAWITHSHA-512"] = "SHA-512withDSA";
algorithms["SHA512/DSA"] = "SHA-512withDSA";
algorithms["SHA-512/DSA"] = "SHA-512withDSA";
algorithms["SHA512WITHDSA"] = "SHA-512withDSA";
algorithms["SHA-512WITHDSA"] = "SHA-512withDSA";
algorithms[NistObjectIdentifiers.DsaWithSha512.Id] = "SHA-512withDSA";
algorithms["ECDSA"] = "SHA-1withECDSA";
algorithms["SHA1/ECDSA"] = "SHA-1withECDSA";
algorithms["SHA-1/ECDSA"] = "SHA-1withECDSA";
algorithms["ECDSAWITHSHA1"] = "SHA-1withECDSA";
algorithms["ECDSAWITHSHA-1"] = "SHA-1withECDSA";
algorithms["SHA1WITHECDSA"] = "SHA-1withECDSA";
algorithms["SHA-1WITHECDSA"] = "SHA-1withECDSA";
algorithms[X9ObjectIdentifiers.ECDsaWithSha1.Id] = "SHA-1withECDSA";
algorithms[TeleTrusTObjectIdentifiers.ECSignWithSha1.Id] = "SHA-1withECDSA";
algorithms["SHA224/ECDSA"] = "SHA-224withECDSA";
algorithms["SHA-224/ECDSA"] = "SHA-224withECDSA";
algorithms["ECDSAWITHSHA224"] = "SHA-224withECDSA";
algorithms["ECDSAWITHSHA-224"] = "SHA-224withECDSA";
algorithms["SHA224WITHECDSA"] = "SHA-224withECDSA";
algorithms["SHA-224WITHECDSA"] = "SHA-224withECDSA";
algorithms[X9ObjectIdentifiers.ECDsaWithSha224.Id] = "SHA-224withECDSA";
algorithms["SHA256/ECDSA"] = "SHA-256withECDSA";
algorithms["SHA-256/ECDSA"] = "SHA-256withECDSA";
algorithms["ECDSAWITHSHA256"] = "SHA-256withECDSA";
algorithms["ECDSAWITHSHA-256"] = "SHA-256withECDSA";
algorithms["SHA256WITHECDSA"] = "SHA-256withECDSA";
algorithms["SHA-256WITHECDSA"] = "SHA-256withECDSA";
algorithms[X9ObjectIdentifiers.ECDsaWithSha256.Id] = "SHA-256withECDSA";
algorithms["SHA384/ECDSA"] = "SHA-384withECDSA";
algorithms["SHA-384/ECDSA"] = "SHA-384withECDSA";
algorithms["ECDSAWITHSHA384"] = "SHA-384withECDSA";
algorithms["ECDSAWITHSHA-384"] = "SHA-384withECDSA";
algorithms["SHA384WITHECDSA"] = "SHA-384withECDSA";
algorithms["SHA-384WITHECDSA"] = "SHA-384withECDSA";
algorithms[X9ObjectIdentifiers.ECDsaWithSha384.Id] = "SHA-384withECDSA";
algorithms["SHA512/ECDSA"] = "SHA-512withECDSA";
algorithms["SHA-512/ECDSA"] = "SHA-512withECDSA";
algorithms["ECDSAWITHSHA512"] = "SHA-512withECDSA";
algorithms["ECDSAWITHSHA-512"] = "SHA-512withECDSA";
algorithms["SHA512WITHECDSA"] = "SHA-512withECDSA";
algorithms["SHA-512WITHECDSA"] = "SHA-512withECDSA";
algorithms[X9ObjectIdentifiers.ECDsaWithSha512.Id] = "SHA-512withECDSA";
algorithms["RIPEMD160/ECDSA"] = "RIPEMD160withECDSA";
algorithms["SHA-512/ECDSA"] = "RIPEMD160withECDSA";
algorithms["ECDSAWITHRIPEMD160"] = "RIPEMD160withECDSA";
algorithms["ECDSAWITHRIPEMD160"] = "RIPEMD160withECDSA";
algorithms["RIPEMD160WITHECDSA"] = "RIPEMD160withECDSA";
algorithms["RIPEMD160WITHECDSA"] = "RIPEMD160withECDSA";
algorithms[TeleTrusTObjectIdentifiers.ECSignWithRipeMD160.Id] = "RIPEMD160withECDSA";
algorithms["GOST-3410"] = "GOST3410";
algorithms["GOST-3410-94"] = "GOST3410";
algorithms["GOST3411WITHGOST3410"] = "GOST3410";
algorithms[CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94.Id] = "GOST3410";
algorithms["ECGOST-3410"] = "ECGOST3410";
algorithms["ECGOST-3410-2001"] = "ECGOST3410";
algorithms["GOST3411WITHECGOST3410"] = "ECGOST3410";
algorithms[CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001.Id] = "ECGOST3410";
oids["MD2withRSA"] = PkcsObjectIdentifiers.MD2WithRsaEncryption;
oids["MD4withRSA"] = PkcsObjectIdentifiers.MD4WithRsaEncryption;
oids["MD5withRSA"] = PkcsObjectIdentifiers.MD5WithRsaEncryption;
oids["SHA-1withRSA"] = PkcsObjectIdentifiers.Sha1WithRsaEncryption;
oids["SHA-224withRSA"] = PkcsObjectIdentifiers.Sha224WithRsaEncryption;
oids["SHA-256withRSA"] = PkcsObjectIdentifiers.Sha256WithRsaEncryption;
oids["SHA-384withRSA"] = PkcsObjectIdentifiers.Sha384WithRsaEncryption;
oids["SHA-512withRSA"] = PkcsObjectIdentifiers.Sha512WithRsaEncryption;
oids["PSSwithRSA"] = PkcsObjectIdentifiers.IdRsassaPss;
oids["SHA-1withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
oids["SHA-224withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
oids["SHA-256withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
oids["SHA-384withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
oids["SHA-512withRSAandMGF1"] = PkcsObjectIdentifiers.IdRsassaPss;
oids["RIPEMD128withRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128;
oids["RIPEMD160withRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160;
oids["RIPEMD256withRSA"] = TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256;
oids["SHA-1withDSA"] = X9ObjectIdentifiers.IdDsaWithSha1;
oids["SHA-1withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha1;
oids["SHA-224withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha224;
oids["SHA-256withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha256;
oids["SHA-384withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha384;
oids["SHA-512withECDSA"] = X9ObjectIdentifiers.ECDsaWithSha512;
oids["GOST3410"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94;
oids["ECGOST3410"] = CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001;
}
/// <summary>
/// Returns a ObjectIdentifier for a give encoding.
/// </summary>
/// <param name="mechanism">A string representation of the encoding.</param>
/// <returns>A DerObjectIdentifier, null if the Oid is not available.</returns>
// TODO Don't really want to support this
public static DerObjectIdentifier GetObjectIdentifier(
string mechanism)
{
if (mechanism == null)
throw new ArgumentNullException("mechanism");
mechanism = mechanism.ToUpper(CultureInfo.InvariantCulture);
string aliased = (string) algorithms[mechanism];
if (aliased != null)
mechanism = aliased;
return (DerObjectIdentifier) oids[mechanism];
}
public static ICollection Algorithms
{
get { return oids.Keys; }
}
public static ISigner GetSigner(
DerObjectIdentifier id)
{
return GetSigner(id.Id);
}
public static ISigner GetSigner(
string algorithm)
{
if (algorithm == null)
throw new ArgumentNullException("algorithm");
algorithm = algorithm.ToUpper(CultureInfo.InvariantCulture);
string mechanism = (string) algorithms[algorithm];
if (mechanism == null)
mechanism = algorithm;
if (mechanism.Equals("MD2withRSA"))
{
return (new RsaDigestSigner(new MD2Digest()));
}
if (mechanism.Equals("MD4withRSA"))
{
return (new RsaDigestSigner(new MD4Digest()));
}
if (mechanism.Equals("MD5withRSA"))
{
return (new RsaDigestSigner(new MD5Digest()));
}
if (mechanism.Equals("SHA-1withRSA"))
{
return (new RsaDigestSigner(new Sha1Digest()));
}
if (mechanism.Equals("SHA-224withRSA"))
{
return (new RsaDigestSigner(new Sha224Digest()));
}
if (mechanism.Equals("SHA-256withRSA"))
{
return (new RsaDigestSigner(new Sha256Digest()));
}
if (mechanism.Equals("SHA-384withRSA"))
{
return (new RsaDigestSigner(new Sha384Digest()));
}
if (mechanism.Equals("SHA-512withRSA"))
{
return (new RsaDigestSigner(new Sha512Digest()));
}
if (mechanism.Equals("RIPEMD128withRSA"))
{
return (new RsaDigestSigner(new RipeMD128Digest()));
}
if (mechanism.Equals("RIPEMD160withRSA"))
{
return (new RsaDigestSigner(new RipeMD160Digest()));
}
if (mechanism.Equals("RIPEMD256withRSA"))
{
return (new RsaDigestSigner(new RipeMD256Digest()));
}
if (mechanism.Equals("PSSwithRSA"))
{
// TODO The Sha1Digest here is a default. In JCE version, the actual digest
// to be used can be overridden by subsequent parameter settings.
return (new PssSigner(new RsaBlindedEngine(), new Sha1Digest()));
}
if (mechanism.Equals("SHA-1withRSAandMGF1"))
{
return (new PssSigner(new RsaBlindedEngine(), new Sha1Digest()));
}
if (mechanism.Equals("SHA-224withRSAandMGF1"))
{
return (new PssSigner(new RsaBlindedEngine(), new Sha224Digest()));
}
if (mechanism.Equals("SHA-256withRSAandMGF1"))
{
return (new PssSigner(new RsaBlindedEngine(), new Sha256Digest()));
}
if (mechanism.Equals("SHA-384withRSAandMGF1"))
{
return (new PssSigner(new RsaBlindedEngine(), new Sha384Digest()));
}
if (mechanism.Equals("SHA-512withRSAandMGF1"))
{
return (new PssSigner(new RsaBlindedEngine(), new Sha512Digest()));
}
if (mechanism.Equals("NONEwithDSA"))
{
return (new DsaDigestSigner(new DsaSigner(), new NullDigest()));
}
if (mechanism.Equals("SHA-1withDSA"))
{
return (new DsaDigestSigner(new DsaSigner(), new Sha1Digest()));
}
if (mechanism.Equals("SHA-224withDSA"))
{
return (new DsaDigestSigner(new DsaSigner(), new Sha224Digest()));
}
if (mechanism.Equals("SHA-256withDSA"))
{
return (new DsaDigestSigner(new DsaSigner(), new Sha256Digest()));
}
if (mechanism.Equals("SHA-384withDSA"))
{
return (new DsaDigestSigner(new DsaSigner(), new Sha384Digest()));
}
if (mechanism.Equals("SHA-512withDSA"))
{
return (new DsaDigestSigner(new DsaSigner(), new Sha512Digest()));
}
if (mechanism.Equals("SHA-1withECDSA"))
{
return (new DsaDigestSigner(new ECDsaSigner(), new Sha1Digest()));
}
if (mechanism.Equals("SHA-224withECDSA"))
{
return (new DsaDigestSigner(new ECDsaSigner(), new Sha224Digest()));
}
if (mechanism.Equals("SHA-256withECDSA"))
{
return (new DsaDigestSigner(new ECDsaSigner(), new Sha256Digest()));
}
if (mechanism.Equals("SHA-384withECDSA"))
{
return (new DsaDigestSigner(new ECDsaSigner(), new Sha384Digest()));
}
if (mechanism.Equals("SHA-512withECDSA"))
{
return (new DsaDigestSigner(new ECDsaSigner(), new Sha512Digest()));
}
if (mechanism.Equals("RIPEMD160withECDSA"))
{
return (new DsaDigestSigner(new ECDsaSigner(), new RipeMD160Digest()));
}
if (mechanism.Equals("SHA1WITHECNR"))
{
return (new DsaDigestSigner(new ECNRSigner(), new Sha1Digest()));
}
if (mechanism.Equals("SHA224WITHECNR"))
{
return (new DsaDigestSigner(new ECNRSigner(), new Sha224Digest()));
}
if (mechanism.Equals("SHA256WITHECNR"))
{
return (new DsaDigestSigner(new ECNRSigner(), new Sha256Digest()));
}
if (mechanism.Equals("SHA384WITHECNR"))
{
return (new DsaDigestSigner(new ECNRSigner(), new Sha384Digest()));
}
if (mechanism.Equals("SHA512WITHECNR"))
{
return (new DsaDigestSigner(new ECNRSigner(), new Sha512Digest()));
}
if (mechanism.Equals("GOST3410"))
{
return new Gost3410DigestSigner(new Gost3410Signer(), new Gost3411Digest());
}
if (mechanism.Equals("ECGOST3410"))
{
return new Gost3410DigestSigner(new ECGost3410Signer(), new Gost3411Digest());
}
if (mechanism.Equals("SHA1WITHRSA/ISO9796-2"))
{
return new Iso9796d2Signer(new RsaBlindedEngine(), new Sha1Digest(), true);
}
if (mechanism.Equals("MD5WITHRSA/ISO9796-2"))
{
return new Iso9796d2Signer(new RsaBlindedEngine(), new MD5Digest(), true);
}
if (mechanism.Equals("RIPEMD160WITHRSA/ISO9796-2"))
{
return new Iso9796d2Signer(new RsaBlindedEngine(), new RipeMD160Digest(), true);
}
throw new SecurityUtilityException("Signer " + algorithm + " not recognised.");
}
public static string GetEncodingName(
DerObjectIdentifier oid)
{
return (string) algorithms[oid.Id];
}
private class NullDigest : IDigest
{
private readonly MemoryStream bOut = new MemoryStream();
public string AlgorithmName
{
get { return "NULL"; }
}
public int GetByteLength()
{
// TODO Is this okay?
return 0;
}
public int GetDigestSize()
{
return (int) bOut.Length;
}
public void Update(byte b)
{
bOut.WriteByte(b);
}
public void BlockUpdate(byte[] inBytes, int inOff, int len)
{
bOut.Write(inBytes, inOff, len);
}
public int DoFinal(byte[] outBytes, int outOff)
{
byte[] res = bOut.ToArray();
res.CopyTo(outBytes, outOff);
return res.Length;
}
public void Reset()
{
bOut.SetLength(0);
}
}
}
}

View File

@@ -0,0 +1,145 @@
using System;
using System.Collections;
using System.Globalization;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Kisa;
using Org.BouncyCastle.Asn1.Nist;
using Org.BouncyCastle.Asn1.Ntt;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
namespace Org.BouncyCastle.Security
{
/// <remarks>
/// Utility class for creating IWrapper objects from their names/Oids
/// </remarks>
public sealed class WrapperUtilities
{
private WrapperUtilities()
{
}
private static readonly Hashtable algorithms = new Hashtable();
// private static readonly Hashtable oids = new Hashtable();
static WrapperUtilities()
{
algorithms[NistObjectIdentifiers.IdAes128Wrap.Id] = "AESWRAP";
algorithms[NistObjectIdentifiers.IdAes192Wrap.Id] = "AESWRAP";
algorithms[NistObjectIdentifiers.IdAes256Wrap.Id] = "AESWRAP";
algorithms[NttObjectIdentifiers.IdCamellia128Wrap.Id] = "CAMELLIAWRAP";
algorithms[NttObjectIdentifiers.IdCamellia192Wrap.Id] = "CAMELLIAWRAP";
algorithms[NttObjectIdentifiers.IdCamellia256Wrap.Id] = "CAMELLIAWRAP";
algorithms[PkcsObjectIdentifiers.IdAlgCms3DesWrap.Id] = "DESEDEWRAP";
algorithms[PkcsObjectIdentifiers.IdAlgCmsRC2Wrap.Id] = "RC2WRAP";
algorithms[KisaObjectIdentifiers.IdNpkiAppCmsSeedWrap.Id] = "SEEDWRAP";
}
public static IWrapper GetWrapper(
DerObjectIdentifier oid)
{
return GetWrapper(oid.Id);
}
public static IWrapper GetWrapper(
string algorithm)
{
string upper = algorithm.ToUpper(CultureInfo.InvariantCulture);
string mechanism = (string) algorithms[upper];
if (mechanism == null)
{
mechanism = upper;
}
switch (mechanism)
{
case "AESWRAP":
return new AesWrapEngine();
case "CAMELLIAWRAP":
return new CamelliaWrapEngine();
case "DESEDEWRAP":
return new DesEdeWrapEngine();
case "RC2WRAP":
return new RC2WrapEngine();
case "SEEDWRAP":
return new SeedWrapEngine();
case "DESEDERFC3211WRAP":
return new Rfc3211WrapEngine(new DesEdeEngine());
case "AESRFC3211WRAP":
return new Rfc3211WrapEngine(new AesFastEngine());
case "CAMELLIARFC3211WRAP":
return new Rfc3211WrapEngine(new CamelliaEngine());
}
// Create an IBufferedCipher and use it as IWrapper (via BufferedCipherWrapper)
IBufferedCipher blockCipher = CipherUtilities.GetCipher(algorithm);
if (blockCipher != null)
return new BufferedCipherWrapper(blockCipher);
throw new SecurityUtilityException("Wrapper " + algorithm + " not recognised.");
}
public static string GetAlgorithmName(
DerObjectIdentifier oid)
{
return (string) algorithms[oid.Id];
}
private class BufferedCipherWrapper
: IWrapper
{
private readonly IBufferedCipher cipher;
private bool forWrapping;
public BufferedCipherWrapper(
IBufferedCipher cipher)
{
this.cipher = cipher;
}
public string AlgorithmName
{
get { return cipher.AlgorithmName; }
}
public void Init(
bool forWrapping,
ICipherParameters parameters)
{
this.forWrapping = forWrapping;
cipher.Init(forWrapping, parameters);
}
public byte[] Wrap(
byte[] input,
int inOff,
int length)
{
if (!forWrapping)
throw new InvalidOperationException("Not initialised for wrapping");
return cipher.DoFinal(input, inOff, length);
}
public byte[] Unwrap(
byte[] input,
int inOff,
int length)
{
if (forWrapping)
throw new InvalidOperationException("Not initialised for Unwrapping");
return cipher.DoFinal(input, inOff, length);
}
}
}
}

View File

@@ -0,0 +1,11 @@
using System;
namespace Org.BouncyCastle.Security.Certificates
{
public class CertificateEncodingException : CertificateException
{
public CertificateEncodingException() : base() { }
public CertificateEncodingException(string msg) : base(msg) { }
public CertificateEncodingException(string msg, Exception e) : base(msg, e) { }
}
}

View File

@@ -0,0 +1,11 @@
using System;
namespace Org.BouncyCastle.Security.Certificates
{
public class CertificateException : GeneralSecurityException
{
public CertificateException() : base() { }
public CertificateException(string message) : base(message) { }
public CertificateException(string message, Exception exception) : base(message, exception) { }
}
}

View File

@@ -0,0 +1,11 @@
using System;
namespace Org.BouncyCastle.Security.Certificates
{
public class CertificateExpiredException : CertificateException
{
public CertificateExpiredException() : base() { }
public CertificateExpiredException(string message) : base(message) { }
public CertificateExpiredException(string message, Exception exception) : base(message, exception) { }
}
}

View File

@@ -0,0 +1,11 @@
using System;
namespace Org.BouncyCastle.Security.Certificates
{
public class CertificateNotYetValidException : CertificateException
{
public CertificateNotYetValidException() : base() { }
public CertificateNotYetValidException(string message) : base(message) { }
public CertificateNotYetValidException(string message, Exception exception) : base(message, exception) { }
}
}

View File

@@ -0,0 +1,11 @@
using System;
namespace Org.BouncyCastle.Security.Certificates
{
public class CertificateParsingException : CertificateException
{
public CertificateParsingException() : base() { }
public CertificateParsingException(string message) : base(message) { }
public CertificateParsingException(string message, Exception exception) : base(message, exception) { }
}
}

View File

@@ -0,0 +1,11 @@
using System;
namespace Org.BouncyCastle.Security.Certificates
{
public class CrlException : GeneralSecurityException
{
public CrlException() : base() { }
public CrlException(string msg) : base(msg) {}
public CrlException(string msg, Exception e) : base(msg, e) {}
}
}