在 .NET Ruby 中使用 3DES 解密十六进制字符串
Decrypt hex strings using 3DES in Ruby from .NET
我正在开发一个 Ruby 项目,该项目正在与我正在与之交换一些加密数据的网络服务进行交互。
我很难解密我从 Ruby 中的 Web 服务返回的内容,尽管在 .NET 方面,它工作正常,以及许多其他基于 Web 或基于桌面的工具可以解决这个问题。
加密方法是带 ECB 且无填充的 3DES。
下面是我一直在做的测试脚本。我已经尝试了所有我能想到的方法来正确解压这些字符串,但无济于事。
require 'openssl'
require 'base64'
def cipher(key, encrypted)
key = key.unpack('a2'*32).map{|x| x.hex}.pack('c'*32)
encrypted = encrypted.unpack('a2'*32).map{|x| x.hex}.pack('c'*32)
OpenSSL::Cipher::ciphers.select{|c| c.include? 'des3' }.map do |cipher_name|
begin
cipher = OpenSSL::Cipher.new(cipher_name)
cipher.padding = 0
cipher.decrypt
cipher.key=key
plain = cipher.update(encrypted) + cipher.final
p "Cipher #{cipher_name} success: #{plain} #{plain.class} #{plain.length} #{plain.encoding.to_s}"
plain
rescue => e
p "Cipher #{cipher_name} failed #{e}"
nil
end
end
end
key = '202FA9B21843D7022B6466DB68327E1F'
encrypted = 'ff6f07e270ebd5c0878c67c999d87ebf'
res1 = cipher key, encrypted
key = '49CE85147B24123718AB3F4539AB1A21'
encrypted = '995604ed8016da8897f1875ebd725529'
res2 = cipher key, encrypted
p res1 == res2 ? "SUCCESS" : "FAIL"
# In both cases, the correct output should be '25588015543912470222703296730936'
3DES 密钥为 24 字节,请使用全长密钥。
3DES 使用 24 字节密钥的三重加密。 202FA9B21843D7022B6466DB68327E1F
是十六进制编码的 16 字节密钥。
尝试重复密钥的前 8 个字节:
202FA9B21843D7022B6466DB68327E1F202FA9B21843D702
某些 3DES 实现会重复 16 字节密钥的 8 字节,但依赖此类实现细节并不是一个好主意。
注意:3DES实际上使用的是168位的密钥,因为没有使用到每个字节的LSb。此外,由于实际上存在三个 DES 调用,因此安全性仅为 112 位。此外,DES 有一些弱密钥。有两种常见模式,ede 和 ded,旨在促进从 DES 到 3DES 的移动,从而增加更多的混乱。
最后:在 CBC 模式下使用随机 IV 从 3DES 转移到 AES。请不要继续不良的安全做法。
我正在开发一个 Ruby 项目,该项目正在与我正在与之交换一些加密数据的网络服务进行交互。
我很难解密我从 Ruby 中的 Web 服务返回的内容,尽管在 .NET 方面,它工作正常,以及许多其他基于 Web 或基于桌面的工具可以解决这个问题。
加密方法是带 ECB 且无填充的 3DES。
下面是我一直在做的测试脚本。我已经尝试了所有我能想到的方法来正确解压这些字符串,但无济于事。
require 'openssl'
require 'base64'
def cipher(key, encrypted)
key = key.unpack('a2'*32).map{|x| x.hex}.pack('c'*32)
encrypted = encrypted.unpack('a2'*32).map{|x| x.hex}.pack('c'*32)
OpenSSL::Cipher::ciphers.select{|c| c.include? 'des3' }.map do |cipher_name|
begin
cipher = OpenSSL::Cipher.new(cipher_name)
cipher.padding = 0
cipher.decrypt
cipher.key=key
plain = cipher.update(encrypted) + cipher.final
p "Cipher #{cipher_name} success: #{plain} #{plain.class} #{plain.length} #{plain.encoding.to_s}"
plain
rescue => e
p "Cipher #{cipher_name} failed #{e}"
nil
end
end
end
key = '202FA9B21843D7022B6466DB68327E1F'
encrypted = 'ff6f07e270ebd5c0878c67c999d87ebf'
res1 = cipher key, encrypted
key = '49CE85147B24123718AB3F4539AB1A21'
encrypted = '995604ed8016da8897f1875ebd725529'
res2 = cipher key, encrypted
p res1 == res2 ? "SUCCESS" : "FAIL"
# In both cases, the correct output should be '25588015543912470222703296730936'
3DES 密钥为 24 字节,请使用全长密钥。
3DES 使用 24 字节密钥的三重加密。 202FA9B21843D7022B6466DB68327E1F
是十六进制编码的 16 字节密钥。
尝试重复密钥的前 8 个字节:
202FA9B21843D7022B6466DB68327E1F202FA9B21843D702
某些 3DES 实现会重复 16 字节密钥的 8 字节,但依赖此类实现细节并不是一个好主意。
注意:3DES实际上使用的是168位的密钥,因为没有使用到每个字节的LSb。此外,由于实际上存在三个 DES 调用,因此安全性仅为 112 位。此外,DES 有一些弱密钥。有两种常见模式,ede 和 ded,旨在促进从 DES 到 3DES 的移动,从而增加更多的混乱。
最后:在 CBC 模式下使用随机 IV 从 3DES 转移到 AES。请不要继续不良的安全做法。