首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JAVA到PHP 7加密

JAVA到PHP 7加密
EN

Stack Overflow用户
提问于 2019-04-30 08:53:36
回答 1查看 844关注 0票数 1

我希望将加密/解密从JAVA复制到PHP。但我的问题是结果不匹配。我对java一无所知,所以我试图理解java中的每一行代码,并使用PHP编写代码。

JAVA

代码语言:javascript
复制
    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中函数的步骤。

  1. 使用sha1创建哈希
  2. 使用utf-8编码将秘钥(从凭据)转换为字节数组。
  3. padd步骤2使用干燥,截断或填充零(如果必要的话),因此副本的指定长度为24。
  4. 使用step3的密钥字节使用DESede初始化秘钥
  5. 用DESede实例创建密码
  6. 用模式初始化密码以使用来自step4的密钥加密
  7. 用utf-8编码将数据(用户名/密码)转换为字节数组加密。
  8. 使用步骤6加密步骤7
  9. 将step8编码为基64格式
  10. 将step9转换为字符串以获得最终的字符串加密消息

我至今所做的一切,

代码语言:javascript
复制
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;
} 
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-30 22:20:51

在Java代码中,加密算法被指定为DESede.这与DESede/ECB/PKCS5Padding相对应,即采用欧洲央行模式和PKCS5 5填充.这意味着PHP代码:

  • 必须应用des-ede3
  • 必须删除与IV相关的所有代码部分(因为欧洲央行模式不使用IV)。
  • 必须删除自定义填充(这绝不是PKCS5 5-填充 )(因为openssl_encrypt默认使用PKCS5 5-填充)。

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

与Java _encrypt-method相对应的PHP可能是:

代码语言:javascript
复制
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,参见这里
  • 使用欧洲央行模式,这本身是不安全的,参见例如这里。更好的选择是CBC或GCM (后者在AES下)。
  • 沙-1用作KDF (它提供了一个太短的键,20个字节,而不是实际需要的24个字节)。更好的选择是PBKDF2

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55917245

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档