【问题标题】:PHP openssl_encrypt script to emulate this Java encryption function (also next stage would be to decrypt)PHP openssl_encrypt 脚本来模拟这个 Java 加密功能(下一阶段也是解密)
【发布时间】:2020-05-09 22:22:09
【问题描述】:

我一直在使用 PHP 脚本来处理 Java 脚本,它们都需要使用相同的过程/iv/key/method 等进行加密和解密,以便双向传输的数据是可翻译的。

我认为我需要使用 opennssl_encrypt 和 openssl_decrypt 并且正在避免使用 mcrypt,而且我已经完成了大部分工作,但出现了问题,我无法弄清楚出了什么问题。

脚本基本上采用盐 (x3) 并运行一个循环直到盐的数量,每次都为输入/循环值添加后缀。

这是Java加密:

VALUE = "myinputvalue"; // test value for string tests
ALGORITHM = "Blowfish";
MODE = "Blowfish/CBC/PKCS5Padding";
IV = "myivmyiv"; //random test value, 8 characters
KEY = "atextstringencryptionkey";
SALT = {"salt1111", "salt2222", "salt3333"};
ITERATIONS = SALT.length;

String encrypt(String value) {
    try{
        SecretKeySpec secretKeySpec = new SecretKeySpec(KEY.getBytes(), ALGORITHM);
        Cipher cipher = Cipher.getInstance(MODE);
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, new IvParameterSpec(IV.getBytes()));
        String valueToEncode = value;
        for(int i = 0; i < ITERATIONS; i++){
            valueToEncode = SALT[i] + valueToEncode;
            byte[] values = cipher.doFinal(valueToEncode.getBytes());
            valueToEncode = Base64.encodeToString(values, Base64.DEFAULT);
            Log.i("Encryption " + (i + 1), valueToEncode);
        }
        return valueToEncode;
    }
    catch(Exception e){
        e.printStackTrace();
        return "";
    }
}

这是我的 PHP 脚本:

$valueToEncode = "myinputvalue";
$cipher_method = "BF-CBC";
$enc_iv = "myivmyiv";
$options = 0;
$enc_key = "atextstringencryptionkey";
$salts = array('salt1111', 'salt2222', 'salt3333');
$arrayLength = count($salts);
$iterations = array();
$i = 0;
while ($i < $arrayLength) {
    $iterations[$i] = strlen($salts[$i]);
    $i++;
}


        $s = 0;

        $valueToEncode = $value;

        while ($s < $arrayLength) {

            $valueToEncode = $salts[$s] . $valueToEncode;

            $valueToEncode = openssl_encrypt($valueToEncode, $cipher_method, $enc_key, $options, $enc_iv);

            $s++;
        }

        $return = $valueToEncode;

这是我能得到的最接近的,它是第一个循环的 100%,但是当返回时输出的结尾出错了。如果我遗漏了一些明显的东西,我很抱歉,我对 PHP 很满意,但加密对我来说是新的,我已经搜索并尝试了很多,但结果都是空的。

我已经尝试实现 base64_decode/base64_encode 以尝试更接近 Java 的工作方式),但它完全抛弃了它,我希望我所缺少的对你们聪明的人来说是简单而明显的。

【问题讨论】:

  • 我知道这不是您想听到的,但是仅使用基本 (Java) 示例有很多错误,您最好替换而不是尝试复制它。密码学不是你随便想出来的东西。像任何其他日常开发任务一样处理它是一个巨大的错误......我强烈建议您聘请专业人士为您完成它,或者至少将其外包给经过实战考验的库。
  • 感谢您的反馈,非常感谢您所说的。这是一个简单的封闭系统,我们只想避免发送纯文本字符串,因此是一个简单的往返字符串加密。
  • 更糟糕的消息:您的循环看起来一点也不像 Java 代码。里面有一个while循环,还有一个变量$s...为什么?这似乎是一种随机尝试的方式,直到出现正确的答案 - 它不会帮助你。尽量模仿 Java 代码,包括标识符名称等。
  • Sorry $s 将在 while 循环中使用(我已将 $i 更正为 $s)。我花了一些时间试图理解并把一些我认为足够的东西放在一起。我很感激指点。我会检查我的代码,看看我能做什么。我得到的第一个循环值是正确的,它是错误的后续循环,所以我认为我在程序上并没有那么远。
  • 如果您只是想不通过网络发送纯文本,只需使用 TLS,这就是它的用途。

标签: java php encryption openssl blowfish


【解决方案1】:

我发现我遇到的问题是由 Java 在 try 循环内的每次迭代结束时创建换行符(\n 值)引起的。

这些 \n 值已被删除,现在输出匹配。

仅供参考,我的 PHP 解密是这样的(请原谅我的惰性循环):

        $s = $arrayLength - 1;

    while ($s >= 0) {

        $valueToDecode = openssl_decrypt($valueToDecode, $cipher_method, $enc_key, $options, $enc_iv);
        $valueToDecode = substr($valueToDecode, $block_size);

        $s--;
    }

感谢那些提供反馈的人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    • 2013-10-28
    • 1970-01-01
    • 2018-09-23
    • 1970-01-01
    相关资源
    最近更新 更多