我需要在C#中复制由遗留存储过程(我无法修改)生成的相同输出,该存储过程在内部使用DBMS_OBFUSCATION_TOOLKIT.DESEncrypt
加密ASCII密码(我确信只有ASCII字符)。
我的C#代码只在输入字符串长度不超过8字节时才得到与oracle相同的结果。
我将问题缩小到oracle的DESEncrypt
不会产生与System.Security.Cryptography.DES
相同的输出,至少就我使用它的方式而言。
我想出了这个Oracle示例代码来说明预期的行为:
declare
key raw(8);
src raw(16);
encrypted raw(16);
begin
key := UTL_RAW.cast_to_raw('MYCRYKEY');
src := utl_raw.cast_to_raw('123456789~~~~~~~');
encrypted := DBMS_OBFUSCATION_TOOLKIT.DESEncrypt(
input => src,
key => UTL_RAW.cast_to_raw('MYCRYKEY'));
dbms_output.put_line('KEY = ' || key);
dbms_output.put_line('SRC = ' || src);
dbms_output.put_line('ENCRYPTED = ' || encrypted);
end;
字符串
上面的代码打印了加密密钥字节、输入字节和结果加密字节的HEX转储,如oracle所见:
KEY = 4D594352594B4559
SRC = 3132333435363738397E7E7E7E7E7E7E
ENCRYPTED = F2E238B83939CBC1C33331A198463076
型
因此,我试图通过在NUnit测试用例中检查这些值来复制相同的结果:
static string ToHex(byte[] bytes)
{
return BitConverter.ToString(bytes).Replace("-", "");
}
[Test]
public void DESTest()
{
byte[] key = Encoding.ASCII.GetBytes("MYCRYKEY");
byte[] src = Encoding.ASCII.GetBytes("123456789~~~~~~~");
using DES des = DES.Create();
des.Key = key;
des.Mode = CipherMode.ECB;
des.Padding = PaddingMode.None;
using ICryptoTransform crypt = des.CreateEncryptor();
byte[] encrypted = crypt.TransformFinalBlock(src, 0, src.Length);
// these are OK
Assert.That(ToHex(key), Is.EqualTo("4D594352594B4559"));
Assert.That(ToHex(src), Is.EqualTo("3132333435363738397E7E7E7E7E7E7E"));
// this one fails
Assert.That(ToHex(encrypted), Is.EqualTo("F2E238B83939CBC1C33331A198463076"));
}
型
输入字节是相同的,但输出在八个字节之后不同:这是最后一个Assert(失败的Assert)产生的消息:
String lengths are both 32. Strings differ at index 17.
Expected: "F2E238B83939CBC1C33331A198463076"
But was: "F2E238B83939CBC1C4388144A4F16DA6"
----------------------------^
型
我尝试了des.Mode
和des.Padding
的各种组合,但我只设法让事情变得更糟:至少在上面的设置中,只要输入字符串长到8字节,我就会得到相同的oracle结果,其他尝试也会失败。
有没有人知道Oracle是怎么得到这个字符串的(我不是加密Maven)?
1条答案
按热度按时间ru9i0ody1#
如果CBC被用作模式并且零向量(8乘以0x00值)被应用为IV,则可以再现密文:
字符串
在
DESENCRYPT
的文档中,我找不到任何关于该模式的参考,只有相关的DES3ENCRYPT
。在那里描述了CBC被用作模式(然而在这里也缺少使用哪个IV)。可能已经知道了,但为了安全起见,应该再次提到:DES已弃用且不安全。此外,使用静态IV(如零IV是一个漏洞)。