当前位置: 首页 > 知识库问答 >
问题:

Java到PHP7加密

南宫俊喆
2023-03-14

我想把加密/解密从Java复制到PHP。但我的问题是结果不匹配。我对Java不了解,所以我试着理解Java的每一行代码,并用PHP编写。

Java


    secretkey: thisisasecretkey
    import java.security.MessageDigest;
    import java.util.Arrays;
    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;

    import org.apache.commons.codec.binary.Base64;

    public class TDESEncrypter {

    public String _encrypt(String message, String secretKey) throws Exception {
    
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        byte[] digestOfPassword = md.digest(secretKey.getBytes("utf-8"));
        byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
            
        SecretKey key = new SecretKeySpec(keyBytes, "DESede");
        Cipher cipher = Cipher.getInstance("DESede");
        cipher.init(Cipher.ENCRYPT_MODE, key);
            
        byte[] plainTextBytes = message.getBytes("utf-8");
        byte[] buf = cipher.doFinal(plainTextBytes);
        byte [] base64Bytes = Base64.encodeBase64(buf);
        String base64EncryptedString = new String(base64Bytes);
            
        return base64EncryptedString;
    }

    public String _decrypt(String encryptedText, String secretKey) throws Exception {
    
        byte[] message = Base64.decodeBase64(encryptedText.getBytes("utf-8"));
            
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        byte[] digestOfPassword = md.digest(secretKey.getBytes("utf-8"));
        byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
        SecretKey key = new SecretKeySpec(keyBytes, "DESede");
            
        Cipher decipher = Cipher.getInstance("DESede");
        decipher.init(Cipher.DECRYPT_MODE, key);
            
        byte[] plainText = decipher.doFinal(message);
            
        return new String(plainText, "UTF-8");
    }
   
}

下面是使用Java来复制PHP中的函数的步骤。

>

  • 使用SHA1创建哈希
  • 使用utf-8编码将secretkey(从凭据)转换为字节数组
  • 使用xeroes填充步骤2,截断或填充零(如有必要),使副本具有指定的长度24
  • 使用DESede使用步骤3中的keybytes初始化Secretkey

    使用DESede实例创建密码

    我到目前为止所做的,

    function encrypt($data, $secret)  { 
    
    
    
        $key = sha1(utf8_encode($secret), true); <-- Step 1 & 2
        $iv = utf8_encode("jvz8bUAx"); <-- Do I use initialise vector on it?
    
        $key .= substr($key, 0, 8); 
    
        $method = 'des-ede3-cbc'; //<-- Is this cypher method correct from the above?
    
    
        if (strlen($data) % 8) {
            $data = str_pad($data, strlen($data) + 8 - strlen($data) % 8, "\0");
        }
    
        $encrypted = openssl_encrypt($data, $method, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); //Force zero padding.
    
        $encrypted = urlencode(base64_encode($encrypted)); // Added the urlencode.....
        return $encrypted;
    } 
    
  • 共有1个答案

    韶浩博
    2023-03-14

    在Java码中,加密算法指定为desede。这对应于desede/ecb/pkcs5padding,即使用ECB-mode和PKCS5-padding。这对于PHP代码意味着:

      必须应用
    • DES-EDE3
    • 必须删除与IV相关的所有代码部分(因为ECB模式不使用IV)
    • 必须删除自定义填充(绝不是PKCS5-Padding),因为openssl_encrypt默认使用PKCS5-Padding)

    在Java代码中,SHA1-hash(大小为20字节)通过附加0值扩展到24字节。这个扩展也必须在PHP代码中完成。

    与Java_encrypt-方法相对应的PHP可能是:

    function encrypt($data, $secret)  {
        $key = sha1(mb_convert_encoding($secret, "UTF-8"), true);                   // Create SHA-1 hash (20 byte) 
        $key = str_pad($key, 24, "\0");                                             // Extend to 24 byte by appending 0-values (would also happen automatically on openssl_encrypt-call)
        $encrypted = openssl_encrypt($data, 'DES-EDE3', $key, OPENSSL_RAW_DATA);    // Encryption: DESede (24 byte key), ECB-mode, PKCS5-Padding
        return base64_encode($encrypted);                                           // Base64-encoding
    }
    

    最后,《Java法典》有许多缺点,例如。

      使用
    • 三重DES。更好的选择是AES,参见此处
    • 使用ECB模式,这本身是不安全的,参见此处。更好的选择是CBC或GCM(后者在AES下)。
    • SHA-1用作KDF(它给出了一个太短的密钥,20个字节,而不是实际需要的24个字节)。更好的选择是PBKDF2。

    后者只是为了完整性,因为它可能是遗留代码,不能因为任何原因进行更改。

     类似资料:
    • 本文向大家介绍迁移PHP版本到PHP7,包括了迁移PHP版本到PHP7的使用技巧和注意事项,需要的朋友参考一下 今天看到微博上说phpng也就是php7合并到master上了,大家都知道我是比较喜欢探讨最新版本的东西,看看有什么特性,我就忍不住升级去了,以前我的PHP版本是5.5.19,然后我就开始了。 然后编译配置参数,我的博客服务器是腾讯云服务器,因为是博客配置比较低。如下: 下边是针对php

    • forp 是一个轻量级的 PHP 扩展,提供 PHP 配置文件数据。 总结的特性 : PHP7 编译时要使用(--enable-dtrace) PHP7使 用时需要设置环境变量(export USE_ZEND_DTRACE=1) 测量的时间和每个函数分配的内存 CPU 使用率 函数调用的文件和行号 输出为谷歌的跟踪事件格式 标题的功能 分组函数 别名的功能(用于匿名函数) forp 是非侵入性的,

    • W:无法获取ppa.launchpad.net/fossfreedom/packagefixes/ubuntu/dist s/jessie/main/binary-i386/packages 404未找到 W:无法获取ppa.launchpad.net/ondrej/php/ubuntu/dists/jessie/main/ binary-amd64/packages 404 W:未能获取ppa.

    • 在这个问题上,我忽略了Linux-PHP7.0和MSSQL(MicrosoftSQL) 我确信我确实按照MS在本页中的要求安装了red hat 7上的驱动程序。但是,我仍然在键入“php-v”时出错: PHP警告:PHP启动:无法加载动态库pdo_sqlsrv.so(尝试: /usr/lib64/php/modules/pdo_sqlsrv.so(/usr/lib64/php/模块/pdo_sql

    • 我在python上做加密,在Java上尝试解密,但总是得到解密错误 我在Java有部分加密和解密信息代码,用RSA编码解密: 不幸的是,我无法在这段代码中进行更改,所以我所能做的就是在python部分中进行更改。这部分工作正常。为了检查,我使用以下代码进行加密: 当我使用来自Java代码的结果进行加密,并将这个结果用于解密Java文件--所有的工作都很好。我需要相同的加密部分,但编写与Python

    • 我试图安装curl在我的ubunutu 14服务器与PHP 7.2安装。我运行以下命令: 但它给出了错误: 读取包裹列表...完成了 构建依赖树 读取状态信息...完成了 E:找不到包php7。0-卷曲 E:无法通过regex'php7找到任何包。0-curl' 然后,我尝试通过运行以下命令来解决此问题: 但这也会导致同样的“找不到包”错误。