当前位置: 首页 > 编程语言 > C#

加密BouncyCastleRSA密钥对并存入SQL2008数据库分享

时间:2023-04-10 16:53:20 C#

EncryptBouncyCastleRSA密钥对并存入SQL2008数据库我有一个生成BouncyCastleRSA密钥对的函数。我需要加密私钥,然后将加密的私钥和公钥存储到单独的SQL2008数据库字段中。我使用以下方法获取密钥对:privatestaticAsymmetricCipherKeyPaircreateASymRandomCipher(){RsaKeyPairGeneratorr=newRsaKeyPairGenerator();r.Init(newKeyGenerationParameters(newSecureRandom(),1024));AsymmetricCipherKeyPairkeys=re;GenerateKeyPair()keys;这是正确的返回密钥,但我不知道如何加密私钥,然后将其存储在数据库中。这是我目前用来加密数据的方法(错误?):publicstaticbyte[]encBytes2(AsymmetricKeyParameterkeyParam,byte[]Key,byte[]IV){RijndaelrjdAlg=Rijndael.Create();rjdAlg.Key=密钥;rjdAlg.IV=IV;CryptoStreamcs=newCryptoStream(ms,rjdAlg.CreateEncryptor(),CryptoStreamMode.Write);byte[]keyBytes=System.Text.Encoding.Unicode.GetBytes(keyParam.ToString());cs.Write(keyBytes,0,keyBytes.Length);cs.关闭();byte[]encryptedData=ms.ToArray();返回加密数据;显然,我将keyParam.ToString()设置的keyBytes转换不正确,因为它只转换KeyParameter名称,而不是实际值。我将之前的密钥对提交给此函数以返回密钥。私人的。另一个问题是,因为我没有加密的公钥,我应该在SQL2008数据库中存储什么格式,nvarchar(256)或其他格式?任何帮助将不胜感激。出于应该清楚的原因,默认(可能是无意的)序列化不适用于私钥,私钥只能在非常有限的情况下写出。BouncyCastle支持PKCS#8,这是“序列化”私钥的相关标准。有一些ASN.1结构称为PrivateKeyInfo和EncryptedPrivateKeyInfo。因为它们在ASN.1中,所以有标准的方法来序列化/反序列化它们。顾名思义,一个用密钥存储密钥,一个用密码加密密钥。对于公钥-这些通常未加密。BC支持X.509标准格式的SubjectPublicKeyInfo以对其进行序列化。在C#构建中,要查看的高级类是:只要对象被标记为可序列化,将对象转换为字节数组的一种方法是使用.Net中的BinaryFormatter类。您需要将此using语句添加到代码文件中:usingSystem.Runtime.Serialization.Formatters.Binary;二进制格式化程序可以将您的类输出到流中。当您打算将对象转换为字节数组时,可以使用System.IO.MemoryStream作为临时存储。内存流memStream=new内存流();然后您可以创建一个新的二进制格式化程序。BinaryFormatter格式器=newBinarryFomatter();并用它来序列化你的对象。formatter.Serialize(memStream,someObject);要获取字节,您可以使用:returnmemStream.ToArray();要反序列化字节数组,您需要将字节写入内存流。memStream.Write(arrBytes,0,arrBytes.Length);返回到流的开头。memStream.Seek(0,SeekOrigin.Begin);然后使用格式化程序重新创建对象。对象obj=(Object)formatter.Deserialize(memStream);如果您已经在使用加密函数,那么在将创建的字节数组存储到数据库之前,您应该能够非常轻松地对其进行加密。希望这有助于您朝着正确的方向前进。如果幸运的话,BouncyCastle对象将被标记为可序列化,否则您将需要一些额外的代码。稍后我将有机会查看BouncyCastle库以测试它并在必要时发布更多代码。...我以前从未使用过BouncyCastle。经过一些测试,看起来publickey和privatekey对象都不是可序列化的,所以你需要将这些对象转换成这样的东西!公钥和私钥似乎将属性公开为各种BouncyCastle.Math.BigInteger值。(也可以从这些BigIntegers构造键)。此外,BigIntegers有一个ToByteArray()函数,也可以从字节数组构造。有用..知道您可以将每个键分解为BigIntegers,然后将这些键分解为字节数组,反之亦然,您可以将所有这些存储在一个可序列化的对象中。一个简单的结构或类可以做,例如[Serializable]privatestructCipherPrivateKey{publicbyte[]modulus;公共字节[]publicExponent;公共字节[]私有指数;公共字节[]p;公共字节[]q;公共字节[]公共字节[]dQ;公共字节[]qInv;}[可序列化]privatestructCipherPublicKey{publicboolisPrivate;公共字节[]模数;公共字节[]指数;序列化对象。AsymmetricCipherKeyPair将公钥和私钥公开为AsymmetricKeyParameter对象。要获得更详细的属性,您需要将这些属性转换为以下内容:privatestaticCipherPublicKeygetCipherPublicKey(Org.BouncyCastle.Crypto.Parameters.RsaKeyParameterscPublic){CipherPublicKeycpub=newCipherPublicKey();cpub.modulus=cPublic.Modulus.ToByteArray();cpub.exponent=cPublic.ExponentArray(To)返回cpub;}privatestaticCipherPrivateKeygetCipherPrivateKey(Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameterscPrivate){CipherPrivateKeycpri=newCipherPrivateKey();();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();返回cpri;使用上述二进制格式化程序,我们可以将我们刚刚创建的可序列化对象转换为字节数组CipherPublicKeycpub=getCipherPublicKey((Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters)keypair.Public);内存流memStream=new内存流();BinaryFormatter格式器=newBinarryFomatter();formatter.Serialize(memStream,cpub);返回memStream.ToArray();如前所述,Desierializing是相反的。拥有反序列化的公共或私有结构后,您可以使用BouncyCastle结构重新创建密钥。这些函数证书了这一点privatestaticOrg.BouncyCastle.Crypto.Parameters.RsaKeyParametersrecreateASymCipherPublicKey(CipherPublicKeycPublicKey)key=newOrg.BouncyCastle.Crypto.Parameters.RsaKeyParameters(cPublicKey.isPrivate,createBigInteger(cPublicKey.modulus),createBigInteger(cPublicKey.exponent));返回键;}privatestaticOrg.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParametersrecreateASymCipherPrivateKey(CipherPrivateKeycPrivateKey){Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters键;key=newOrg.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));返回键;如果您出于任何原因需要重新创建原始密钥对:AsymmetricKeyParameterpubl=(AsymmetricKeyParameter)recreateASymCipherPublicKey(cKeyPair.publicKey);AsymmetricKeyParameterpriv=(AsymmetricKeyParameter)recreateASymCipherPrivateKey(cKeyPairPairmmCprivateKey)newAsymmetricCipherKeyPair(publ,priv);希望一切都有意义!代码示例应该可以帮助您正确的方法是使用Peters的建议。我在下面添加了一个小的C#代码示例:varkeyPair=GetKeypair();PrivateKeyInfoprivateKeyInfo=PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair.Private);byte[]serializedKey=privateKeyInfo.ToAsn1Object().GetDerEncoded();AsymmetricKeyKeyParameter1=反序列化PrivateKeyFactory.CreateKey(serializedKey);Assert.AreEqual(keyPair.Private,deserializedKey1);AsymmetricKeyParameterdeserializedKey2=PrivateKeyFactory.CreateKey(privateKeyInfo);Assert.AreEqual(keyPair.Private,deserializedKey2);此示例使用BouncyCastleAPI。请注意,此示例不会加密密钥。CreatePrivateKeyInfo方法被重载以允许使用密码作为密钥保护。关于问题的第二部分,应该用于存储密钥的数据类型是VARBINARY(256)。回到问题的第一部分,您实际上可以选择让SQLServer为您处理加密。当然,您是否愿意这样做取决于您的应用程序要求是什么,但如果可以的话,我会仔细检查一下。我们在这里非常基础,只使用对称密钥和Triple-DES。首先,数据库有一个主密钥,用于保护证书和非对称密钥。主密钥使用Triple-DES加密。CREATEMASTERKEYENCRYPTIONBYPASSWORD='supersecretpassword'SQLServer2005/2008可以生成自己的X.509证书来保护用于加密实际数据的密钥。CREATECERTIFICATEExampleCertificateWITHSUBJECT='thisisjustsomemetadata'有许多加密对称密钥(证书、密码、其他密钥)的选项和许多受支持的算法。但是对于这个例子,我们将使用我们的证书。CREATESYMMETRICKEYExampleKeyWITHALGORITHM=TRIPLE_DESENCRYPTIONBYCERTIFICATEEncryptTestCert密钥需要使用与加密时相同的方法进行解密。在我们的例子中,这将是我们创建的证书。DECLARE@ValueVARCHAR(50)SET@Value='supersecretdata!'OPENSYMMETRICKEYExampleKeyDECRYPTIONBYCERTIFICATEExampleCertificateUPDATESomeTableSETSomeColumn=ENCRYPTBYKEY(KEY_GUID('ExampleKey'),@Value)解密同样简单。OPENSYMMETRICKEYExampleKeyDECRYPTIONBYCERTIFICATEExampleCertificateSELECTCONVERT(VARCHAR(50),DECRYPTBYKEY(SomeColumn))ASDecryptedDataFROMSomeTable希望这能解决你的问题,或者至少让你接触到其他解决方案(尽管在C#应用程序中有加密经验的人可能会发现上面代码中的错误)。如果您的需求需要数据,您甚至无法通过纯文本连接到SQLServer,这显然不行(好吧,您实际上可以创建到SQLServer的SSL连接...)。以上就是C#学习教程:加密BouncyCastleRSA密钥对并存入SQL2008数据库。代表立场,如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: