1

我正在使用 Ruby 尝试加密一个字符串,该字符串将存储在数据库中并由 Flash/Actionscript 应用程序读取/解密。

该应用程序使用这种河豚实现

我已经尝试过创建兼容字符串的opensslcrypt/blowfish方法。两者都不匹配,也不匹配 Flash 应用程序所期望的。

我从哪里开始让它发挥作用?

irb(main):001:0> require 'openssl'
=> true
irb(main):002:0> require 'crypt/blowfish'
=> true
irb(main):007:0> require 'base64'
=> true
irb(main):003:0> key = "foo"
=> "foo"
irb(main):004:0> plain = "some string" 
=> "some string"
irb(main):005:0> blowfish = Crypt::Blowfish.new(key)
=> 
irb(main):006:0> enc = blowfish.encrypt_block(plain)
=> "\xF5\xAFB\x12=\xB9\xDB\f"
irb(main):008:0> Base64.encode64(enc)
=> "9a9CEj252ww=\n"

# Now, openssl version

irb(main):009:0> cipher = OpenSSL::Cipher::Cipher.new('bf-cbc').send(:encrypt)
=> #<OpenSSL::Cipher::Cipher:0x00000000f26430>
irb(main):010:0> cipher.key = Digest::SHA256.digest(key)
=> ",&\xB4kh\xFF\xC6\x8F\xF9\x9BE<\x1D0A4\x13B-pd\x83\xBF\xA0\xF9\x8A^\x88bf\xE7\xAE"
irb(main):011:0> enc = cipher.update(plain) << cipher.final
=> "m<\xDB\xC1B\x02p\xB0\xD6\xD0\xA4\xE8XyY\x99"
irb(main):012:0> Base64.encode64(enc)
=> "bTzbwUICcLDW0KToWHlZmQ==\n"

编辑

这是我们在 AS3 中所做的(使用上面提到的河豚代码):

import com.lassieadventurestudio.Blowfish;
import fl.controls.Button;
import fl.controls.TextInput;
import flash.events.MouseEvent;

var $key:String = "foo";

BTN_Submit.label = "Encrypt";
BTN_Submit.addEventListener(MouseEvent.CLICK, onSubmit);

function onSubmit(event:MouseEvent):void
{
        trace("INP_Pass.text, ", INP_Pass.text);

        var $encryption:String = Blowfish.encrypt(INP_Pass.text, $key);
        TXT_Output.text = $encryption;
}

BTN_Decrypt.label = "Decrypt";
BTN_Decrypt.addEventListener(MouseEvent.CLICK, decrypt);

function decrypt(event:MouseEvent):void
{
        TXT_Output2.text = Blowfish.decrypt(TXT_Output.text, $key);

}
4

1 回答 1

1

问题是您尝试的两种方式都使用 CBC 模式,但您链接到的 AS3 示例使用的是 ECB 模式。

您可以使用以下方法实现相同的目的:

cipher = OpenSSL::Cipher.new('bf-ecb')
cipher.encrypt
cipher.key = key
enc = cipher.update(plain) << cipher.final

但请注意,这根本不是一个好的加密方案,原因有几个(ECB、Blowfish 密钥长度、直接用作密钥的密码......),正如文章中所写,它只会阻止窥探,但这不会对致力于它的人构成障碍。

编辑:

我查看了 AS3 实现,但不幸的是我无法重现那里给出的示例结果。但我相信博客中的 Blowfish 实现很糟糕,你不应该使用它。他们在那里为密钥使用普通密码,更糟糕的是,他们首先对它们进行 Base64 解码以获得原始字节,从而有效地将已经坏的熵再次降低 3/4 倍。

Ruby OpenSSL 的 Blowfish 实现采用 16 字节的密钥,因此使用较短的密钥重现结果不会很幸运。我建议您执行以下操作:

使用 AES 而不是 Blowfish。虽然 Blowfish 从未被“破坏”,但其 56 位的有效安全性可以被暴力破解。

不要使用密码作为密钥。使用加密安全的随机字节。例如,在 Ruby 中执行此操作的一种简单方法是:

 key = cipher.random_key

您可能想在 AS3 中找到类似的东西。

不要使用欧洲央行模式。使用 CBC 模式,或者,如果您的 OpenSSL 版本可用(要求 >=1.0.0),甚至更好,使用 CTR 模式。

您可能想查看Cipher 文档以获得更多关于实现可能被认为是安全的东西的建议。

于 2012-07-24T12:37:03.993 回答