无无无言 2023-02-25 05:38 采纳率: 50%
浏览 71
已结题

如何使用 java 实现 Laravel中(openssl)encrypt和decrypt,之前系统用的PHP,现在想换成java

请使用java解密我的密文,并贴出测试成功的代码谢谢

密文:eyJpdiI6ImdtbmJZZlwvZW81UEFvbm9aWE5RYU13PT0iLCJ2YWx1ZSI6IjZqS2xQQzBQYjdoRUlhRDVmemNuUHNTaFUxd0M1VHI1Ylg3MVcrUndWZDQ9IiwibWFjIjoiY2NjZmQ2MGFkYjAyMGU4MTQxYTlmZWY1ZjYyZjFmODI2ZmY1MDdlNTFkNWJmOWQ4OTAzNTAxNmUzNTg4ZjBjZSJ9
密文BASE64解码后:{"iv":"gmnbYf\/eo5PAonoZXNQaMw==","value":"6jKlPC0Pb7hEIaD5fzcnPsShU1wC5Tr5bX71W+RwVd4=","mac":"cccfd60adb020e8141a9fef5f62f1f826ff507e51d5bf9d89035016e3588f0ce"}

APP_KEY=base64:+90gHlNsoj6J0G9OepRfOkW/9IJHiK+bGS1Lt+wzn+M=

  • 写回答

7条回答 默认 最新

  • pzzhao 2023-02-25 11:47
    关注

    按照这个大佬 (https://mayee.cc/2022/02/10/2022-02-10-01 )的代码搞定了,我就不重复造轮子了,如果你不想用hutool的话可以在找我改

    代码示例

    import cn.hutool.core.codec.Base64;
    import cn.hutool.core.util.RandomUtil;
    import cn.hutool.crypto.Mode;
    import cn.hutool.crypto.Padding;
    import cn.hutool.crypto.digest.HMac;
    import cn.hutool.crypto.digest.HmacAlgorithm;
    import cn.hutool.crypto.symmetric.AES;
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONObject;
    import lombok.extern.slf4j.Slf4j;
    import org.phprpc.util.PHPSerializer;
    
    import java.lang.reflect.InvocationTargetException;
    import java.util.Objects;
    
    @Slf4j
    public class Encrypter {
    
        /**
         * 秘钥
         */ 
        private final String key = "+90gHlNsoj6J0G9OepRfOkW/9IJHiK+bGS1Lt+wzn+M=";
    
        /*
            php 在外部需要配置加密模式 AES-128-CBC 或 AES-256-CBC,并且只支持这两种模式。
            但 java 无需指定模式,会根据秘钥长度来自动判断。
         */
    
    
        /**
         * 加密给定的文本
         *
         * @param value 原文对象
         * @return 密文
         */
        public String encrypt(Object value) {
            byte[] iv = RandomUtil.randomBytes(16);
            byte[] serialize;
            PHPSerializer ps = new PHPSerializer();
            try {
                serialize = ps.serialize(value);
            } catch (IllegalAccessException | InvocationTargetException e) {
                log.error("Could not serialize the data: {}", e.getMessage());
                return null;
            }
            AES aes = new AES(Mode.CBC, Padding.PKCS5Padding, Base64.decode(key), iv);
            String encrypt = aes.encryptBase64(serialize);
            String mac = this.hash(Base64.encode(iv), encrypt);
            JSONObject json = new JSONObject(true);
            json.put("iv", Base64.encode(iv));
            json.put("value", encrypt);
            json.put("mac", mac);
            return Base64.encode(json.toJSONString());
        }
    
        /**
         * 解密给定的文本
         *
         * @param payload 密文
         * @return 原文
         */
        public <T> T decrypt(String payload, Class<T> type) {
            JSONObject payloadObj = this.getJsonPayload(payload);
            byte[] iv = Base64.decode(payloadObj.getString("iv"));
            AES aes = new AES(Mode.CBC, Padding.PKCS5Padding, Base64.decode(key), iv);
            byte[] decrypt = aes.decrypt(payloadObj.getString("value"));
            PHPSerializer ps = new PHPSerializer();
            try {
                return (T) ps.unserialize(decrypt, type);
            } catch (IllegalAccessException | InvocationTargetException e) {
                log.error("Could not unserialize the data: {}", e.getMessage());
            }
            return null;
        }
    
        private JSONObject getJsonPayload(String payload) {
            JSONObject payloadObj = JSON.parseObject(Base64.decodeStr(payload));
            if (!this.validPayload(payloadObj)) {
                throw new RuntimeException("The payload is invalid.");
            }
            if (!this.validMac(payloadObj)) {
                throw new RuntimeException("The MAC is invalid.");
            }
            return payloadObj;
        }
    
        /**
         * 验证 payload 是否有效
         *
         * @param payloadObj
         * @return
         */
        private boolean validPayload(JSONObject payloadObj) {
            if (Objects.nonNull(payloadObj)) {
                return payloadObj.containsKey("iv") && payloadObj.containsKey("value") && payloadObj.containsKey("mac") &&
                        Base64.decode(payloadObj.getString("iv")).length == 16;
            }
            return false;
        }
    
        private boolean validMac(JSONObject payloadObj) {
            byte[] bytes = RandomUtil.randomBytes(16);
            String calculated = this.calculateMac(payloadObj, bytes);
            HMac mac = new HMac(HmacAlgorithm.HmacSHA256, bytes);
            return Objects.equals(mac.digestHex(payloadObj.getString("mac")), calculated);
        }
    
        private String calculateMac(JSONObject payloadObj, byte[] bytes) {
            HMac mac = new HMac(HmacAlgorithm.HmacSHA256, bytes);
            return mac.digestHex(this.hash(payloadObj.getString("iv"), payloadObj.getString("value")));
        }
    
        private String hash(String iv, String value) {
            HMac mac = new HMac(HmacAlgorithm.HmacSHA256, Base64.decode(key));
            return mac.digestHex(iv + value);
        }
    
    
        public static void main(String[] args) {
            String payload = "eyJpdiI6ImdtbmJZZlwvZW81UEFvbm9aWE5RYU13PT0iLCJ2YWx1ZSI6IjZqS2xQQzBQYjdoRUlhRDVmemNuUHNTaFUxd0M1VHI1Ylg3MVcrUndWZDQ9IiwibWFjIjoiY2NjZmQ2MGFkYjAyMGU4MTQxYTlmZWY1ZjYyZjFmODI2ZmY1MDdlNTFkNWJmOWQ4OTAzNTAxNmUzNTg4ZjBjZSJ9";
            String decrypt = new Encrypter().decrypt(payload, String.class);
            System.out.println("解密:"+ decrypt);
    
            String encrypt = new Encrypter().encrypt("168168.qwe");
            System.out.println("加密:" +encrypt);
        }
    }
    

    结果

    解密:168168.qwe
    加密:eyJpdiI6IlhKZEJYQlVCazMyWmtGSFhjck9Vc0E9PSIsInZhbHVlIjoidG02b2RKTWIxKzgzUWFGejBqVEVWN3RyRmNUK2VlV3VUS1VsT08wVDhHdz0iLCJtYWMiOiJjYzY5NzcwNjIwYjc5OGQyNzYxMTNkYzI2YWEwMTZhYzM3MWE4MjY3MDBkNDMzMzQ3NGQyNTRjMDNkYzQyYTg5In0=
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(6条)

报告相同问题?

问题事件

  • 系统已结题 3月5日
  • 已采纳回答 2月25日
  • 创建了问题 2月25日