我有一个生成BouncyCastle密钥对的函数。我需要加密私钥,然后将加密的私钥和公钥存储到单独的SQL2008数据库字段中。
我使用以下命令来获取密钥对:
private static AsymmetricCipherKeyPair createASymRandomCipher()
{
RsaKeyPairGenerator r = new RsaKeyPairGenerator();
r.Init(new KeyGenerationParameters(new SecureRandom(), 1024));
AsymmetricCipherKeyPair keys = r.GenerateKeyPair();
return keys;
}这可以很好地返回密钥,但我不确定如何加密私钥并随后将其存储在数据库中。
这就是我目前使用的加密数据(不正确?):
public static byte[] encBytes2(AsymmetricKeyParameter keyParam, byte[] Key, byte[] IV)
{
MemoryStream ms = new MemoryStream();
Rijndael rjdAlg = Rijndael.Create();
rjdAlg.Key = Key;
rjdAlg.IV = IV;
CryptoStream cs = new CryptoStream(ms, rjdAlg.CreateEncryptor(), CryptoStreamMode.Write);
byte[] keyBytes = System.Text.Encoding.Unicode.GetBytes(keyParam.ToString());
cs.Write(keyBytes, 0, keyBytes.Length);
cs.Close();
byte[] encryptedData = ms.ToArray();
return encryptedData;
}显然,我要转换keyParam.ToString()的keyBytes设置是不正确的,因为它只转换KeyParameter名称,而不是实际值。我将keys.Private的前一个密钥对返回提交给此函数。
另一个问题是,由于我没有加密公钥,我应该以什么格式将其存储在SQL2008数据库、nvarchar(256)或其他数据库中?
任何帮助都将不胜感激。
发布于 2010-02-02 23:42:41
出于一些应该明确的原因,默认(可能是无意的)序列化不能很好地处理私钥,私钥应该只在非常有限的情况下写出。
BouncyCastle支持PKCS#8,这是“序列化”私钥的相关标准。有称为PrivateKeyInfo和EncryptedPrivateKeyInfo的ASN.1结构。因为它们在ASN.1中,所以有标准的方法来序列化/反序列化它们。顾名思义,一个以明文存储密钥,另一个基于密码加密密钥。
对于公钥-这些通常不会被加密。BC支持用于序列化它们的X.509标准格式的SubjectPublicKeyInfo。
在C#构建中,要查看的高级类如下:
发布于 2009-05-15 15:03:47
只要对象被标记为可序列化,将对象转换为字节数组的一种方法就是使用.Net中的BinaryFormatter类。
您需要将以下using语句添加到代码文件中:
using System.Runtime.Serialization.Formatters.Binary;二进制格式化程序可以将您的类输出到流。当您打算将对象转换为字节数组时,可以使用System.IO.MemoryStream作为临时存储。
MemoryStream memStream = new MemoryStream();然后,您可以创建一个新的二进制格式化程序。
BinaryFormatter formatter = new BinarryFomatter();并用它来序列化你的对象。
formatter.Serialize(memStream, someObject);要获取可以使用的字节数,请执行以下操作:
return memStream.ToArray();要反序列化字节数组,需要将字节写入内存流。
memStream.Write(arrBytes, 0, arrBytes.Length);返回到流的开头。
memStream.Seek(0, SeekOrigin.Begin);然后使用格式化程序重新创建对象。
Object obj = (Object)formatter.Deserialize(memStream);如果您已经在使用加密函数,那么在将创建的字节数组存储到数据库中之前,您应该能够非常容易地对其进行加密。
希望这能帮助你朝着正确的方向前进。如果您幸运的话,BouncyCastle对象将被标记为可序列化的,否则您将需要一些额外的代码。稍后,我将有机会查看BouncyCastle库,以便能够对此进行测试,并在必要时发布更多代码。
..。我以前从未使用过BouncyCastle。经过一些测试后,似乎公钥和私钥对象是不可序列化的,因此您需要将这些对象转换为可序列化的对象!
看起来,公钥和私钥将属性公开为各种BouncyCastle.Math.BigInteger值。(密钥也可以从这些BigIntegers构造)。此外,BigIntegers有一个ToByteArray()函数,也可以从字节数组构造。非常有用..
知道您可以将每个键分解为BigIntegers,然后将它们转换为字节数组,并且反向操作也是可能的,因此您可以将所有这些内容存储在一个可序列化的对象中。一个简单的结构或类可以做如下工作:
[Serializable]
private struct CipherPrivateKey
{
public byte[] modulus;
public byte[] publicExponent;
public byte[] privateExponent;
public byte[] p;
public byte[] q;
public byte[] dP;
public byte[] dQ;
public byte[] qInv;
}
[Serializable]
private struct CipherPublicKey
{
public bool isPrivate;
public byte[] modulus;
public byte[] exponent;
}这为我们提供了一对易于使用的可序列化对象。
AsymmetricCipherKeyPair将公钥和私钥作为AsymmetricKeyParameter对象公开。要获得更详细的属性,您需要将这些属性转换为以下内容:
keyPair.Public to BouncyCastle.Crypto.Parameters.RsaKeyParameters keyPair.Private to BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters
下面的函数将把它们转换成之前声明的结构:
private static CipherPublicKey getCipherPublicKey(Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters cPublic)
{
CipherPublicKey cpub = new CipherPublicKey();
cpub.modulus = cPublic.Modulus.ToByteArray();
cpub.exponent = cPublic.Exponent.ToByteArray();
return cpub;
}
private static CipherPrivateKey getCipherPrivateKey(Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters cPrivate)
{
CipherPrivateKey cpri = new CipherPrivateKey();
cpri.dP = cPrivate.DP.ToByteArray();
cpri.dQ = cPrivate.DQ.ToByteArray();
cpri.modulus = cPrivate.Modulus.ToByteArray();
cpri.p = cPrivate.P.ToByteArray();
cpri.privateExponent = cPrivate.Exponent.ToByteArray();
cpri.publicExponent = cPrivate.PublicExponent.ToByteArray();
cpri.q = cPrivate.Q.ToByteArray();
cpri.qInv = cPrivate.QInv.ToByteArray();
return cpri;
}使用前面提到的二进制格式化程序,我们可以将刚刚创建的可序列化对象转换为字节数组。
CipherPublicKey cpub = getCipherPublicKey((Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters)keypair.Public);
MemoryStream memStream = new MemoryStream();
BinaryFormatter formatter = new BinarryFomatter();
formatter.Serialize(memStream, cpub);
return memStream.ToArray();反其道而行之,如前所述。一旦反序列化了公共或私有结构,就可以使用BouncyCastle构造器重新创建密钥。这些函数说明了这一点。
private static Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters recreateASymCipherPublicKey(CipherPublicKey cPublicKey)
{
Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters key;
key = new Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters(
cPublicKey.isPrivate,
createBigInteger(cPublicKey.modulus),
createBigInteger(cPublicKey.exponent));
return key;
}
private static Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters recreateASymCipherPrivateKey(CipherPrivateKey cPrivateKey)
{
Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters key;
key = new Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters(
createBigInteger(cPrivateKey.modulus),
createBigInteger(cPrivateKey.publicExponent),
createBigInteger(cPrivateKey.privateExponent),
createBigInteger(cPrivateKey.p),
createBigInteger(cPrivateKey.q),
createBigInteger(cPrivateKey.dP),
createBigInteger(cPrivateKey.dQ),
createBigInteger(cPrivateKey.qInv));
return key;
}如果您出于任何原因需要重新创建原始密钥对:
AsymmetricKeyParameter publ = (AsymmetricKeyParameter)recreateASymCipherPublicKey(cKeyPair.publicKey);
AsymmetricKeyParameter priv = (AsymmetricKeyParameter)recreateASymCipherPrivateKey(cKeyPair.privateKey);
AsymmetricCipherKeyPair keyPair = new AsymmetricCipherKeyPair(publ, priv);希望这一切都是有意义的!代码示例应该会对您有所帮助。
发布于 2010-09-28 18:57:42
正确的方法是使用Peters的建议。
我在下面包含了一个小的C#代码示例:
var keyPair = GetKeypair();
PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair.Private);
byte[] serializedKey = privateKeyInfo.ToAsn1Object().GetDerEncoded();
AsymmetricKeyParameter deserializedKey1 = PrivateKeyFactory.CreateKey(serializedKey);
Assert.AreEqual(keyPair.Private, deserializedKey1);
AsymmetricKeyParameter deserializedKey2 = PrivateKeyFactory.CreateKey(privateKeyInfo);
Assert.AreEqual(keyPair.Private, deserializedKey2);该示例使用Bouncy Castle API。请注意,示例不会加密密钥。CreatePrivateKeyInfo方法被重载以允许使用密码作为密钥的保护。
https://stackoverflow.com/questions/844997
复制相似问题