目前,我对ActionScript 3还比较陌生,在将其提交给服务器进行处理之前,我一直试图使用as3crypto库对一些数据进行河豚算法加密。我知道您可以使用https,但是大多数浏览器仍然显示出站数据,使得用户很容易伪造请求。这就是为什么我想让用户看到页面请求,但不能在不解密的情况下读取数据。
不幸的是,对于我来说,除了代码中的注释之外,as3crypto库上的去中心功能几乎是不存在的(这并没有太大帮助)。我用一些静态函数设置了闪存端,以“实现”as3crypto河豚加密,它们只适用于flash中的加密/解密。当我试图使用mcrypt库在PHP中使用密钥解密时,问题就出现了。我得到的输出不是原始代码,我花了几天时间试图找出为什么没有效果。
下面是代码和解释。在这个例子中,使用的键是'mykey‘(没有引号),编码的数据是'Hello’(同样没有引号)。
Flash代码(as3crypto河豚助手):
package lib.ef.crypto
{
import com.hurlant.util.Base64;
import com.hurlant.crypto.Crypto;
import flash.utils.ByteArray;
import com.hurlant.crypto.symmetric.IPad;
import com.hurlant.crypto.symmetric.ICipher;
import com.hurlant.crypto.symmetric.NullPad;
public class Blowfish
{
/**
* Encrypts a string.
* @param text The text string to encrypt.
* @param key A cipher key to encrypt the text with.
*/
static public function encrypt($text:String, $key:String=""):String
{
var cryptKey:ByteArray = new ByteArray();
cryptKey.writeUTF( $key );
var iPad:IPad = new NullPad();
var crypt:ICipher = Crypto.getCipher('blowfish-cfb',cryptKey,iPad);
iPad.setBlockSize( crypt.getBlockSize() );
var cryptText:ByteArray = new ByteArray();
cryptText.writeUTF( $text );
crypt.encrypt( cryptText );
trace( Base64.encodeByteArray( cryptText ) );
return null;
}
static public function decrypt($text:String, $key:String=""):String
{
return new String();
}
}
}它的输出因运行而异,但就本例运行而言,我得到的base64编码输出是“EkKo9htSJUnzBmxc0A==”。
当我将该代码引入PHP时,在传递到下面的方法对其进行解密之前,将对其进行base64解码:
public static function decrypt($crypttext,$key)
{
if( !function_exists('mcrypt_module_open') ) trigger_error('The blowfish encryption class requires the Mcrypt library to be compiled into PHP.');
$plaintext = '';
$td = mcrypt_module_open('blowfish', '', 'cfb', '');
$blocksize = mcrypt_enc_get_block_size($td);
$iv = substr($crypttext, 0, $blocksize);
$crypttext = substr($crypttext, $blocksize);
if (true)
{
mcrypt_generic_init($td, $key, $iv);
$plaintext = mdecrypt_generic($td, $crypttext);
}
return $plaintext;
}此时,输出完全不可读。我怀疑这个问题可能与以下事实有关:河豚的as3crypto实现不正确(不太可能),或者可能与它使用的填充(当前为空填充)有关,或者最后,我认为它可能与as3crypto中随机生成的初始化向量有关,而不是被加到编码字符串的前面?最后一次我还不能真正测试,因为as3crypto库很大,很复杂,而且文档也不多。我已经在谷歌上搜索了这个问题,并测试了几天的所有内容,我只是不断地想出PHP中无法使用的数据。我知道如果我能让Flash到PHP系统工作,我可以反向工程它,让PHP的Flash加密也运行。
我欢迎所有关于这件事的意见,因为它实际上已经让我在晚上睡不着觉了,谢谢:)
我今天做了一些进一步的测试,并试图看看它是否像我所怀疑的那样是初始化向量。我不相信这就是问题所在。我在闪存中修改了一些内容,以便获得用于生成编码输出的IV的输出:
package lib.ef.crypto
{
import com.hurlant.util.Base64;
import com.hurlant.crypto.Crypto;
import flash.utils.ByteArray;
import com.hurlant.crypto.symmetric.IPad;
import com.hurlant.crypto.symmetric.ICipher;
import com.hurlant.crypto.symmetric.NullPad;
public class Blowfish
{
/**
* Encrypts a string.
* @param text The text string to encrypt.
* @param key A cipher key to encrypt the text with.
*/
static public function encrypt($text:String, $key:String=""):String
{
var cryptKey:ByteArray = new ByteArray();
cryptKey.writeUTF( $key );
var iPad:IPad = new NullPad();
var crypt = Crypto.getCipher('blowfish-cfb',cryptKey,iPad);
iPad.setBlockSize( crypt.getBlockSize() );
var cryptText:ByteArray = new ByteArray();
cryptText.writeUTF( $text );
crypt.encrypt( cryptText );
cryptText.position = 0;
var iv:ByteArray = crypt.IV;
iv.position = 0;
trace( Base64.encodeByteArray( iv ) );
trace( Base64.encodeByteArray( cryptText ) );
return null;
}
static public function decrypt($text:String, $key:String=""):String
{
return new String();
}
}
}在这个例子中,我得到了一个编码的IV '1bcGpqIbWRc=‘和加密的'XpgART3hNQO10vcgLA==’数据--在对它们进行base64_decode()处理之后,我将它们插入一个修改后的PHP函数中:
public static function decrypt($crypttext,$key,$iv=NULL)
{
if( !function_exists('mcrypt_module_open') ) trigger_error('The blowfish encryption class requires the Mcrypt library to be compiled into PHP.');
$plaintext = '';
$td = mcrypt_module_open('blowfish', '', 'cfb', '');
if( $iv === NULL ){
$ivsize = mcrypt_enc_get_iv_size($td);
echo '<pre>'.$ivsize.'</pre>';
$iv = substr($crypttext, 0, $ivsize);
echo '<pre>'.strlen($iv).'</pre>';
$crypttext = substr($crypttext, $ivsize);
}
if ($iv)
{
mcrypt_generic_init($td, $key, $iv);
$plaintext = mdecrypt_generic($td, $crypttext);
}
return $plaintext;
}甚至这个输出也是不正确的。我做了一些测试,以确保IV在Flash和PHP中都是正确的大小,但出于某种原因,PHP端无法解密flash中的河豚编码输出。我尝试在as3crypto中同时使用NULL和as3crypto填充,但两者都不适用于PHP的系统。我已经进行了测试,以确保在Flash和PHP中IV字符串是相同的。他们都用同样的钥匙。两者都在使用循环流化床模式。我还是不明白。相同的算法、相同的密钥、相同的IV、相同的模式,但它们不能相互解密。在我看来,河豚的as3crypto实现可能是错误的。有人能证实这一点吗?
发布于 2011-08-10 13:35:29
在对as3Crypto库文件和演示代码进行了一些深入研究之后,我发现问题在于,我需要使用简单的getCipher函数,而不是blowfish cfb模式。然后调用crypt.encyrpt( cryptText )的加密输出将是以算法IV为前缀的,因此您只需对Base64.encodeByteArray( cryptText )进行一次调用,就可以获得要发送给PHP的输出。当您以上面的方式初始化PHP时,它将从字符串中分割出IV并正确地解密。希望这能帮助其他人解决这个问题。
以下是“正确的”闪存和PHP代码*,适用于所有只需要快速复制/粘贴解决方案的用户:P
*注意:我必须在两个代码示例中删除一些特定于我的应用程序的调用,并且没有对它们进行测试以确保它们是100%的功能,但是它们应该足够地说明概念/结构,如果它们不能正确地“开箱即用”,您可以很容易地修复它们供您使用。
PHP“助手”类:
class Blowfish
{
public static function encrypt($plaintext,$key)
{
if( !function_exists('mcrypt_module_open') ) trigger_error('The blowfish encryption class requires the Mcrypt library to be compiled into PHP.');
$td = mcrypt_module_open('blowfish', '', 'cbc', '');
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
mcrypt_generic_init($td, $key, $iv);
$crypttext = mcrypt_generic($td, $plaintext);
mcrypt_generic_deinit($td);
$out = $iv.$crypttext;
return $out;
}
public static function decrypt($crypttext,$key)
{
if( !function_exists('mcrypt_module_open') ) trigger_error('The blowfish encryption class requires the Mcrypt library to be compiled into PHP.');
$plaintext = '';
$td = mcrypt_module_open('blowfish', '', 'cbc', '');
$ivsize = mcrypt_enc_get_iv_size($td);
$iv = substr($crypttext, 0, $ivsize);
$crypttext = substr($crypttext, $ivsize);
if ($iv)
{
mcrypt_generic_init($td, $key, $iv);
$plaintext = mdecrypt_generic($td, $crypttext);
}
return $plaintext;
}
}Flash“助手”类:
package [your package name]
{
import com.hurlant.util.Base64;
import com.hurlant.util.Hex;
import com.hurlant.crypto.Crypto;
import flash.utils.ByteArray;
import com.hurlant.crypto.symmetric.IPad;
import com.hurlant.crypto.symmetric.ICipher;
import com.hurlant.crypto.symmetric.IVMode;
import com.hurlant.crypto.symmetric.NullPad;
public class Blowfish
{
/**
* Encrypts a string.
* @param txt The text string to encrypt.
* @param k A cipher key to encrypt the text with.
*/
static public function encrypt(txt:String, k:String=""):String
{
var kdata:ByteArray;
kdata = Hex.toArray(Hex.fromString(k));
var data:ByteArray;
data = Hex.toArray(Hex.fromString(txt));
var pad:IPad = new NullPad;
var mode:ICipher = Crypto.getCipher('simple-blowfish-cbc', kdata, pad);
pad.setBlockSize(mode.getBlockSize());
mode.encrypt(data);
return Base64.encodeByteArray( data );
}
/**
* Decrypts a string.
* @param txt The text string to decrypt.
* @param k A cipher key to decrypt the text with.
*/
static public function decrypt(txt:String, k:String=""):String
{
var kdata:ByteArray;
kdata = Hex.toArray(Hex.fromString( Base64.decode( k ) ));
var data:ByteArray;
data = Hex.toArray(Hex.fromString(txt));
var pad:IPad = new NullPad;
var mode:ICipher = Crypto.getCipher('simple-blowfish-cbc', kdata, pad);
pad.setBlockSize(mode.getBlockSize());
mode.decrypt(data);
data.position = 0;
return data.readUTFBytes( data.bytesAvailable );
}
}
}发布于 2013-03-10 15:36:48
谢谢!请参见此处正确的“解密”:
static public function decrypt(txt:String, k:String=""):String{
var kdata:ByteArray;
kdata = Hex.toArray(Hex.fromString(k));
var data:ByteArray;
data = Base64.decodeToByteArray(txt);
var pad:IPad = new NullPad;
var mode:ICipher = Crypto.getCipher('simple-blowfish-cbc', kdata, pad);
pad.setBlockSize(mode.getBlockSize());
mode.decrypt(data);
data.position = 0;
return data.readUTFBytes( data.bytesAvailable );
}https://stackoverflow.com/questions/6977595
复制相似问题