CFB模式下的TripleDES,C#和Crypto++的区别这是我的问题:我有一个C++中的遗留代码(使用crypto++v5.6.1),我在C#中开发了一个新代码(.NET3.5使用System.Security.Cryptography)。我无法更改C++代码,但我需要能够解密以前加密的数据,并且以前的应用程序必须能够解密我将使用新C#代码加密的数据。两种情况下使用的算法都是TripleDESwithCFBciphermode,但是最后加密的数据是不一样的,字节数和第一个字节是一样的,除此之外其他所有字节都不一样。填充(添加零)是在C++代码中手动完成的。所以我将PaddingValue设置为PaddingMode.Zeros。(我也尝试在C#代码中手动添加零,它没有改变任何东西)。我尝试使用不同的System.Text.Encoding但结果是相同的(实际上测试的字符是“纯”ASCII(即:0到126之间))。在C++代码中,MandatoryBlockSize()的值是8,所以我也将FeedbackSize设置为8。但是如果我理解它写的是什么,它实际上是我的IV的大小,不是吗?密钥大小为24个字节(3个不同的密钥),IV为8个字节长。它们在两个代码中是相同的。如果我在这两种情况下都使用CBC模式,结果是相同的(但是,正如我所说,我无法更改遗留代码......),OFB和CTS模式抛出异常(一个不可用,另一个不兼容)在我在.NET应用程序上,所以无法比较结果。我试过用Mono,.Net3.5和4.0版本,或者用visual,用.Net3.5或4.0,4个加密结果是一样的,但是和原来的不一样。现在我真的不知道要测试什么...我宁愿不将Crypto++包装在C++/CLI项目中以使用它而不是System.Security.Cryptography。有没有人有建议或可以告诉我做错了什么?这是C++代码:void*CryptData(BYTE*bDataIn,LONGlIn,LONG*lOut,byte*key,byte*iv){byte*bIn;字节*bOut;长l2,lb;CFB_FIPS_Mode::加密encryption_DES_EDE3_CFB;encryption_DES_EDE3_CFB.SetKeyWithIV(key,sizeof(key),iv,sizeof(iv));lb=encryption_DES_EDE3_CFB.MandatoryBlockSize();l2=((lIn+lb-1)/lb)*lb;bIn=(byte*)malloc(l2);bOut=(byte*)malloc(l2);内存集(bIn,0,l2);memset(bOut,0,l2);memcpy(bIn,bDataIn,lIn);encryption_DES_EDE3_CFB.ProcessString(bOut,bIn,l2);*lOut=l2;返回bOut;这是C#代码:publicFibxCrypt(){_cryptoAlgo=newTripleDESCryptoServiceProvider();//_cryptoAlgo.GenerateKey();_cryptoAlgo.Key=_key;//_cryptoAlgo.GenerateIV();_cryptoAlgo.IV??=_iv;_cryptoAlgo.Mode=CipherMode.CFB;_cryptoAlgo.Padding=PaddingMode.Zeros;_encoding=newUTF8Encoding();}privateMemoryStreamEncryptingString(stringplainText,outlongencryptSize){//检查ifarguments。(纯文本==空||plainText.Length<=0)thrownewArgumentNullException("plainText");//创建一个解密器来执行流转换。ICryptoTransform加密器=_cryptoAlgo.CreateEncryptor();//创建用于加密的流。//使用(MemoryStreammsEncrypt=newMemoryStream())MemoryStreammsEncrypt=newMemoryStream();encryptSize=((plainText.Length+_cryptoAlgo.FeedbackSize-1)/_cryptoAlgo.FeedbackSize)*_cryptoAlgo.FeedbackSize;using(CryptoStreamcsEncrypt=newCryptoStream(msEncrypt,encryptor,CryptoStreamMode.Write)){using(StreamWriterswEncrypt=newStreamWriter(csEncrypt,_encoding)){//将所有数据写入流。swEncrypt.Write(纯文本);}}//返回加密的内存流。返回msEncrypt;编辑:我试图直接使用加密而不是使用流,我有同样的问题privateMemoryStreamEncryptingString(stringplainText,outlongencryptSize){//检查参数。如果(plainText==null||plainText.Length<=0)thrownewArgumentNullException("plainText");ICryptoTransform加密器=_cryptoAlgo.Create;Encryptor()byte[]cipherData=encryptor.TransformFinalBlock(_encoding.GetBytes(plainText),0,plainText.Length);//返回加密的内存流。返回msEncrypt;您更改的FeedBackSize与CFB操作模式(msdn文档)有关。因此,您还应该检查C++和C#中的反馈大小是否相同。我相信您的错误可能是C++代码和C#代码之间的恶意BlockSizes。您是否尝试过在C#实现中设置BlockSize=8?这些都不正确:CFB_FIPS_Mode::Encryptionenc;enc.SetKeyWithIV(key,sizeof(key),iv,sizeof(iv));sizeof(key)和sizeof(iv)返回指针的大小,而不是安全参数的大小。你应该使用这个:enc.SetKeyWithIV(key,DES_EDE3::DEFAULT_KEYLENGTH,iv,DES_EDE3::BLOCKSIZE);如果它适用于.Net,那么您应该更愿意增加像Mcrypt和.Net这样的库的反馈大小;而不要减少Crypto++中的反馈大小。这是因为当反馈大小不是完整块大小时,某些模式会失去安全性。我不知道这是否适用于.Net,但它应该考虑或尝试:publicFibxCrypt(){_cryptoAlgo=newTripleDESCryptoServiceProvider();_cryptoAlgo.Key=_key;_cryptoAlgo.IV??=_iv;_cryptoAlgo.Mode=CipherMode.CFB;_cryptoAlgo.Padding=PaddingMode.Zeros;//添加:_cryptoAlgo.FeedbackSize=_cryptoAlgo.BlockSize;如果您不能在.Net中调整反馈大小,这里是如何在Crypto++中更改反馈大小。您将AlgorithmParameters设置为保存反馈大小参数,然后使用其他参数调用SetKey:(),1/*8位*/)(Name::IV(),ConstByteArrayParameter(iv,DES_EDE3::BLOCKSIZE));CFB_FIPS_Mode::加密编码;enc.SetKey(key,24,DES_EDE3::DEFAULT_KEYLENGTH);...}我不清楚在FIPS模式下运行的CFB模式是否允许如此小的反馈大小。如果它抛出异常,您只需要使用CFB_Mode。由于operator()重载,AlgorithmParameters看起来有点奇怪。您可以在Crypto++wiki上的NameValuePairs阅读有关它的信息。其他感兴趣的wiki页面是TripleDES和CFB模式。----另一个需要注意的是文本编码。由于UTF-16,它经常导致.Net和Java中的互操作性问题。UTF-8和ASCII引起的问题最少。你应该没问题,因为你encode=newUTF8Encoding()。但是,如果事情仍然对您不起作用,那么您就是一条未编码或未解释的字节消息。例如,在.Net和Crypto++中使用它:bytemsg[4]={0x01,0x02,0x03,0x04};不解释这四个字节,因此它对步骤进行编码。以上就是C#学习教程:CFB模式下的TripleDES,C#和Crypto++的不同之处,分享所有内容。如果对你有用,需要了解更多C#学习教程,希望大家多多关注——本文来自网络收藏,不代表立场,如涉及侵权,请点击有权联系管理员删除。如需转载请注明出处:
