为 c# bouncycastle 编写 php MCrypt twofish
Posted
技术标签:
【中文标题】为 c# bouncycastle 编写 php MCrypt twofish【英文标题】:writing php MCrypt twofish for c# bouncycastle 【发布时间】:2016-04-30 12:04:55 【问题描述】:我正在学习如何使用 BouncyCastle c# 密码库进行加密。我不想发送消息,所以我不考虑安全性等。 我已经在 Visual Studio 中编写了我的 c# 代码。
这就是问题所在。我在 CFB 模式下使用 Twofish 对文本“Hello World!”进行了加密。关键是1234567812345678。我用过phpfiddlehttp://phpfiddle.org/在线工具。
$algo = 'twofish';
$mode = 'cfb';
$cipher = mcrypt_module_open($algo,'',$mode,'');
$key = hex2bin('31323334353637383132333435363738'); //1234567812345678
$iv = hex2bin('00000000000000000000000000000000');
mcrypt_generic_init($cipher, $key, $iv);
$plaintext = utf8_encode('Hello World!');
$encrypted = mcrypt_encrypt($algo, $key, $plaintext, $mode, $iv);
printf("<br>Encrypted text: %s<br><br>",base64_encode($encrypted));
$decrypted = mcrypt_decrypt($algo, $key, $encrypted, $mode, $iv);
printf("<br>Decrypted text: %s (%s)<br><br>",$decrypted,bin2hex($decrypted));
mcrypt_generic_deinit($cipher);
mcrypt_module_close($cipher);
结果如下
cfdJ+M6MAzG4WJMb (Base64)
然后我创建了一个 c# 版本来解密相同的文本
// ASCII encoding and Zero padding
encoding = Encoding.ASCII
padding = IBlockCipherPadding.zeroBytePadding
// Set up the engine and cipher types
baseCipher = new TwofishEngine();
blockSize = baseCipher.GetBlockSize();
modeCipher = new CfbBlockCipher(baseCipher, blockSize);
cipher = padding == null ? new PaddedBufferedBlockCipher(modeCipher) : new PaddedBufferedBlockCipher(modeCipher, padding);
// convert the strings to byte array and create a dummy 000000.. iv
byte[] iv = new byte[blockSize]; // i.e. 16 bytes of zero
keyBytes = _encoding.GetBytes(key); //1234567812345678
inputBytes = Convert.FromBase64String(inp);
// initiate the cipher with iv parameters
cipher.Init(true, new ParametersWithIV(new KeyParameter(keyBytes), iv));
// do the decryption
console.write(_encoding.GetString(cipher.DoFinal(inputBytes)) + "\n";)
但这给了我垃圾。我得到 HIl1oVW�rEdIp�
关闭 (H.l.o.W.r.d.) 但所有其他字母都是错误的!
ECB 模式工作正常,所以它必须与初始化向量有关。
PHP 和 c# 之间有什么我还没学过的区别吗?
在这种情况下,我的 c# 代码在哪里不正确?
【问题讨论】:
加密是 8 位字节,而不是可打印的字符。通常,并非所有 8 位字节都是可打印的,因此是问题中的输出。十六进制调试的最佳格式。 感谢 zaph,但需要更改哪一步。我使用 mcrpyt 使用 utf8 编码对文本进行加密。加密的输出是 Base64。我是否需要在 c# 中更改加密步骤或以不同方式解密? 【参考方案1】:好的。所以我终于解决了。我对密码块模式的理解中的一个基本错误。 CFB 和 OFB 是流密码而不是填充缓冲分组密码。
因此密码设置应该是
modeCipher = new CfbBlockCipher(baseCipher,8); // Allways 8 bits for a stream cipher !!
cipher = new StreamBlockCipher(modeCipher);
(cipher.doFinal 也发生了变化,但这里没有显示)
现在可以正常使用了。
【讨论】:
以上是关于为 c# bouncycastle 编写 php MCrypt twofish的主要内容,如果未能解决你的问题,请参考以下文章
无法将“Org.BouncyCastle.Asn1.DerSequence”类型的对象转换为“Org.BouncyCastle.Asn1.DerInteger”类型
使用 mbedtls 生成的 RSA 签名,无法使用 C# (bouncycastle) 应用程序进行验证