PHP实现DESede/ECB/PKCS5Padding加密算法兼容Java SHA1PRNG

这里写自定义目录标题

  • 背景
  • JAVA代码
  • 解决思路
    • PHP解密

背景

公司PHP开发对接一个Java项目接口,接口返回数据有用DESede/ECB/PKCS5Padding加密,并且key也使用了SHA1PRNG加密了,网上找了各种办法都不能解密,耗了一两天的时间,一度怀疑人生……

JAVA代码

public class DESUtil {

    private static final String KEY_ALGORITHM = "DESede";
    private static final String DEFAULT_CIPHER_ALGORITHM = "DESede/ECB/PKCS5Padding";

    /* DES加密 */
    public static String encrypt(String content, final String key) {
        try {
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
            byte[] byteContent = content.getBytes(StandardCharsets.UTF_8.name());
            cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(key));
            byte[] result = cipher.doFinal(byteContent);
            return Base64.encodeBase64String(result);
        } catch (Exception ex) {
            log.error("【DES加密失败】:", ex);
        }
        return null;
    }

    /* DES解密 */
    public static String decrypt(String content, final String key) {
        try {
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key));
            byte[] result = cipher.doFinal(Base64.decodeBase64(content));
            return new String(result, StandardCharsets.UTF_8.name());
        } catch (Exception ex) {
            log.error("【DES解密失败】:", ex);
        }
        return null;
    }
    
    public static SecretKeySpec getSecretKey(final String key) {
        KeyGenerator kg = null;
        try {
            kg = KeyGenerator.getInstance(KEY_ALGORITHM);
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(key.getBytes(StandardCharsets.UTF_8.name()));
            kg.init(secureRandom);
            SecretKey secretKey = kg.generateKey();
            return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);
        } catch (NoSuchAlgorithmException ex) {
            log.error("【DES生成秘钥失败】:", ex);
        } catch (UnsupportedEncodingException e) {
            log.error("【DES生成秘钥失败】:", e);
        }
        return null;
    }
}

解决思路

终于找到了一个类似问题,可是要会员才能看,作为一名穷DS,哪有这么富有,灵机一动在某鱼花了1大洋看了解决思路,果然是金钱的力量,功夫不负有心人啊,终于寻到stackoverflow有个类似问题。

PHP实现DESede/ECB/PKCS5Padding加密算法兼容Java SHA1PRNG_第1张图片

上面Java代码中的secretKey变量的比特值,使用Base64Utils.encode后得到base64字符串
然后在php中使用base64_decode解码串,得到密钥key

PHP解密

/* 3DES解密 */
    public function desDecrypt($content) {
        $key=$this->config['desKey'];
        $key=base64_decode($key);
        $content = base64_decode($content);
        // 解密数据
        $plaintext = openssl_decrypt($content, 'DES-EDE3', $key, OPENSSL_RAW_DATA);
        return $plaintext;
    }

你可能感兴趣的:(java,php,python)