【问题标题】:Implementing this Java password encryption algorithm in PHP在 PHP 中实现这个 Java 密码加密算法
【发布时间】:2010-08-06 07:38:21
【问题描述】:

我正在尝试在 PHP 中实现 Funambol 移动同步服务器中使用的密码加密算法,但由于我来自非 Java 背景,所以我遇到了困难。代码本身看起来很简单:

encryptionKey   = "Omnia Gallia in tres partes divida est";
byte[] newValue = new byte[24];
System.arraycopy(encryptionKey, 0, newValue, 0, 24);
encryptionKey   = newValue;

KeySpec keySpec             = new DESedeKeySpec(encryptionKey);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESEde");
Cipher cipher               = Cipher.getInstance("DESEde");    
SecretKey key               = keyFactory.generateSecret(keySpec);

cipher.init(Cipher.ENCRYPT_MODE, key);

cipherBytes = cipher.doFinal(plainBytes);

我不一定要寻找一个完整的解决方案,而是我可以在 PHP 方面使用的指针。 mcrypt 可以处理这个问题吗?我还需要什么?这在 PHP 中是否可行?

对于好奇的人:我正在为 Funambol 服务器构建一个界面,我希望能够使用 PHP 从界面本身添加用户。

【问题讨论】:

  • 看起来很简单,因为算法使用了一些框架。第一步是查看是否存在与 Triple DES 等效的 PHP(请参阅 en.wikipedia.org/wiki/Triple_DES )。如果可能的话,你可以考虑在Java端添加一些可以直接通过PHP调用的外部接口。
  • 我相信 Julius Caesar 的引用应该是 divisa 而不是 divida - 无论如何它是:Gallia est omnis divisa in partes tres from thelatinlibrary.com/caesar/gall1.shtml ---- 虽然使用不正确的版本可能会更棘手:p
  • 这并不重要,但使用 System.arraycopy 获取字符串的字节表示时,当您获得 unicode 中代码点 255 以上的字符时,很可能会中断。您可能希望改为使用 String.getBytes()。

标签: java php funambol


【解决方案1】:

终于解决了,在这里发帖以防有人需要使用 PHP 加密或解密 Funambol 的密码:

class Funambol_auth {

    private static $key = "Omnia Gallia in tres par";

    public static function encrypt($data) {
        $size = mcrypt_get_block_size('des', 'ecb');
        $data = self::pkcs5_pad($data, $size);
        $mcrypt_module = mcrypt_module_open(MCRYPT_TRIPLEDES, '', 'ecb', '');
        $mcrypt_iv     = mcrypt_create_iv(mcrypt_enc_get_iv_size($mcrypt_module), MCRYPT_RAND);
        $key_size      = mcrypt_enc_get_key_size($mcrypt_module);

        mcrypt_generic_init($mcrypt_module,self::$key,$mcrypt_iv);
        $encrypted = base64_encode(mcrypt_generic($mcrypt_module, $data));
        mcrypt_module_close($mcrypt_module);

        return $encrypted;
    }

    public static function decrypt($data) {
        $mcrypt_module = mcrypt_module_open(MCRYPT_TRIPLEDES, '', 'ecb', '');
        $mcrypt_iv     = mcrypt_create_iv(mcrypt_enc_get_iv_size($mcrypt_module), MCRYPT_RAND);
        $decrypted     = mcrypt_decrypt(MCRYPT_TRIPLEDES, self::$key, base64_decode($data), 'ecb', $mcrypt_iv);
        mcrypt_module_close($mcrypt_module);

        return self::pkcs5_unpad($decrypted);
    }

    private static function pkcs5_pad($text, $blocksize) {
        $pad = $blocksize - (strlen($text) % $blocksize);
        return $text . str_repeat(chr($pad), $pad);
    }

    private static function pkcs5_unpad($text) {
        $pad = ord($text{strlen($text)-1});
        if ($pad > strlen($text)) return false;
        if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) return false;
        return substr($text, 0, -1 * $pad);
    }
}

【讨论】:

    【解决方案2】:

    这可能是你想要的:

    $td = mcrypt_module_open('tripledes', '', 'ecb', '');
    $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
    $nKeySize = mcrypt_enc_get_key_size($td);
    
    $key = substr(sha1($encryptionKey), 0, $nKeySize);
    mcrypt_generic_init($td, $key, $iv);
    $nDataSize = strlen($plainBytes);
    $sDataSize = substr(dechex(ceil(log($nDataSize,16))), -1) . dechex($nDataSize);
    
    $cipherBytes = mcrypt_generic($td, $sDataSize . $plainBytes);
    
    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);
    

    请注意,由于 3DES 加密/解密数据块的方式,我使用数据加密 $sDataSize

    【讨论】:

      最近更新 更多