2011-08-08 36 views
0

我對ActionScript3目前很陌生,在將它提交給服務器進行處理之前,一直試圖使用as3crypto庫來加密一些數據。我知道你可以使用https,但大多數瀏覽器仍然顯示出站數據,這使得用戶很容易僞造請求。這就是爲什麼我想讓用戶看到頁面請求,但無法解密就無法讀取數據的原因。在PHP中解密as3crypto blowfish數據的錯誤

不幸的是,對於我來說,as3crypto庫的文檔除了代碼中的註釋之外幾乎是不存在的(這並沒有太多幫助)。我已經用一些靜態函數設置了flash的一面,以實現as3crypto blowfish加密,並且它們僅適用於閃存中的加密/解密。當我嘗試使用密鑰在PHP中使用mcrypt庫進行解密時,問題就出現了。我得到的輸出不是原始代碼,我花了幾天的時間試圖找出爲什麼無濟於事。

下面是代碼和解釋。就本例而言,所用的密鑰是'mykey'(不帶引號),編碼數據是'Hello World'(再次沒有引號)。

的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; 
} 

此時輸出完滿成功完全不可讀。我懷疑這個問題可能與這樣一個事實有關,即blowfish的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(); 
     } 

    } 
} 

對於這個例子我的「1bcGpqIbWRc =」的編碼IV和編碼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中的blowfish編碼輸出。我已經嘗試在as3crypto中使用NULL和PKCS5填充,並且都不適用於PHP系統。我已經測試過,以確保在Flash和PHP中IV字符串都是相同的。他們都使用相同的密鑰。兩者都使用CFB模式。我不明白。相同的算法,相同的密鑰,相同的IV,相同的模式,但它們不能相互解密。在我看來,河豚的as3crypto實施可能是不正確的。任何人都可以確認嗎?

回答

1

在對as3Crypto庫文件和演示代碼進行了一些挖掘之後,我發現問題在於我需要使用getCipher函數和simple-blowfish-cfb模式來代替blowfish-cfb模式。然後調用crypt.encyrpt(cryptText)的加密輸出將爲已有的前綴爲算法IV,因此您只需調用Base64.encodeByteArray(cryptText)即可將輸出發送到PHP。當你按照上面的方式初始化PHP時,它將切斷字符串中的IV並正確解密。希望這可以幫助任何伴隨這個問題的人。

「正確的」閃光燈和PHP代碼*低於所有你TLDR; ERS誰只是想快速複製/粘貼的解決方案: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; 
    } 

} 

閃電俠 「助手」 類:

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); 
     } 

    } 
} 
+0

另外,現在的加密標準是AES加密。遵守標準通常會更好。 – christopher

1

感謝名單! 在這裏看到正確的「解密」:

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); 

} 
相關問題