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

求java/php大佬帮帮忙?

章嘉致
2025-01-08

最近遇到一个需求,需要对接第三方平台,然后对面只给公钥和私钥 ,本身我是用php开发的,第三方的demo 是java 头大完全不知道什么意思,看不懂java写法 有没有大哥帮我写个php的类
这是第三方demo提供的加密加签方法

以下是完整文件
package com.example.guojindemo.utils;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class SignUtils {

public static void main(String[] args) throws Exception {


}

/**
 * 生成DES密码,注意:当前版本需要为ASCII可见字符作为密码
 *
 * @return
 * @throws Exception
 */
public static SecretKey genDESKey() throws Exception {
    // return KeyGenerator.getInstance("DES").generateKey(); !!!!!注意!!!!暂不支持这种方式
    int targetStringLength = 16;
    Random random = new Random();

    //随机生成16位可见字符密码, JDK8+
    String key = random.ints('0', 'z' + 1)
            .limit(targetStringLength)
            .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
            .toString();

    DESKeySpec dks = new DESKeySpec(key.getBytes());
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
    return keyFactory.generateSecret(dks);
}
/**
 * 加密,用对方公钥加密,我方私钥加签
 *
 * @param raw
 * @param desKey
 * @param publicKey
 * @param privateKey
 * @return
 * @throws Exception
 */
public static Map<String,Object> encrypt(String raw, SecretKey desKey, PublicKey publicKey, PrivateKey privateKey) throws Exception {
    Map<String,Object> ret = new HashMap<>();

    /* ------------- SHA1withRSA 算法进行签名 ------------------ */
    Signature sign = Signature.getInstance("SHA1withRSA");
    sign.initSign(privateKey);

    byte[] rawBytes = raw.getBytes();
    //签名
    sign.update(rawBytes);
    byte[] signature = sign.sign();
    //转base64
    String sign_data = Base64.getEncoder().encodeToString(signature);
    ret.put("sign_data",sign_data);

    /* ------------- RSA 加密 DES 秘钥------------------ */
    Cipher rsa_enc_cipher = Cipher.getInstance("RSA");
    // 用对方的公钥加密
    rsa_enc_cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    byte[] rsa_enc_Data = rsa_enc_cipher.doFinal(desKey.getEncoded());
    //转base64
    String encrypt_key = Base64.getEncoder().encodeToString(rsa_enc_Data);
    ret.put("encrypt_key",encrypt_key);

    /* ------------- DES 加密业务数据 ------------------ */
    Cipher des_enc_cipher = Cipher.getInstance("DES");
    des_enc_cipher.init(Cipher.ENCRYPT_MODE, desKey);
    byte[] des_enc_Data = des_enc_cipher.doFinal(rawBytes);
    String seal_data = Base64.getEncoder().encodeToString(des_enc_Data);
    ret.put("seal_data",seal_data);
    return ret;
}
/**
 * 解密,用我方私钥解密,对方公钥验签
 *
 * @param privateKey
 * @param publicKey
 * @return
 * @throws Exception
 */
public static String decrypt(String encrypt_key,String seal_data,String sign_data,
                             PrivateKey privateKey, PublicKey publicKey) throws Exception {
    /* ------------- RSA 解密 DES 秘钥------------------ */
    //base64 解码
    byte[] decodedKey = Base64.getDecoder().decode(encrypt_key);
    // RSA 解密 DES 秘钥
    Cipher rsa_dec_cipher = Cipher.getInstance("RSA");
    // 用自己的私钥进行解密
    rsa_dec_cipher.init(Cipher.DECRYPT_MODE, privateKey);
    byte[] decryptedKey = rsa_dec_cipher.doFinal(decodedKey);
    //获取 DES 秘钥
    //SecretKey desKey = new SecretKeySpec(decryptedKey, 0, decryptedKey.length, "DES");
    DESKeySpec dks = new DESKeySpec(decryptedKey);
    SecretKey desKey = SecretKeyFactory.getInstance("DES").generateSecret(dks);


    /* ------------- DES 解密业务数据 ------------------ */
    byte[] decodedSealData = Base64.getDecoder().decode(seal_data);
    Cipher des_dec_cipher = Cipher.getInstance("DES");
    des_dec_cipher.init(Cipher.DECRYPT_MODE, desKey);
    byte[] rawBytes = des_dec_cipher.doFinal(decodedSealData);
    String raw = new String(rawBytes, "UTF-8");

    /* ------------- 验签 ------------------ */
    Signature verifySign = Signature.getInstance("SHA1withRSA");
    verifySign.initVerify(publicKey);
    verifySign.update(rawBytes);

    byte[] signature = Base64.getDecoder().decode(sign_data);
    if (!verifySign.verify(signature)) {
        throw new Exception("验签不通过!");
    }
    return raw;
}
public static PublicKey getPublicKey(String key) throws Exception {
    byte[] decodedKey = Base64.getDecoder().decode(key);
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    PublicKey publicKey = keyFactory.generatePublic(keySpec);
    return publicKey;
}

public static PrivateKey getPrivateKey(String key) throws Exception {
    byte[] decodedKey = Base64.getDecoder().decode(key);
    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
    return privateKey;
}

}

由于时间上不允许我研究太久 实在没办法,求各位大哥帮帮忙

共有1个答案

诸修伟
2025-01-08

在PHP中启用OpenSSL扩展

<?php

class SignUtils {

    /**
     * 生成DES密码, 注意: 当前版本需要为ASCII可见字符作为密码
     *
     * @return string
     * @throws Exception
     */
    public static function genDESKey() {
        $targetStringLength = 16;
        $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $charactersLength = strlen($characters);
        $randomString = '';
        for ($i = 0; $i < $targetStringLength; $i++) {
            $randomString .= $characters[rand(0, $charactersLength - 1)];
        }
        return $randomString;
    }

    /**
     * 加密, 用对方公钥加密, 我方私钥加签
     *
     * @param string $raw
     * @param string $desKey
     * @param resource $publicKey
     * @param resource $privateKey
     * @return array
     * @throws Exception
     */
    public static function encrypt($raw, $desKey, $publicKey, $privateKey) {
        $ret = [];

        // 签名
        if (!openssl_sign($raw, $signature, $privateKey, OPENSSL_ALGO_SHA1)) {
            throw new Exception('签名失败');
        }
        $sign_data = base64_encode($signature);
        $ret['sign_data'] = $sign_data;

        // RSA 加密 DES 秘钥
        if (!openssl_public_encrypt($desKey, $rsa_enc_Data, $publicKey)) {
            throw new Exception('RSA 加密 DES 秘钥失败');
        }
        $encrypt_key = base64_encode($rsa_enc_Data);
        $ret['encrypt_key'] = $encrypt_key;

        // DES 加密业务数据
        $des_enc_Data = openssl_encrypt($raw, 'DES-ECB', $desKey, OPENSSL_RAW_DATA);
        if ($des_enc_Data === false) {
            throw new Exception('DES 加密业务数据失败');
        }
        $seal_data = base64_encode($des_enc_Data);
        $ret['seal_data'] = $seal_data;

        return $ret;
    }

    /**
     * 解密, 用我方私钥解密, 对方公钥验签
     *
     * @param string $encrypt_key
     * @param string $seal_data
     * @param string $sign_data
     * @param resource $privateKey
     * @param resource $publicKey
     * @return string
     * @throws Exception
     */
    public static function decrypt($encrypt_key, $seal_data, $sign_data, $privateKey, $publicKey) {
        // RSA 解密 DES 秘钥
        $decodedKey = base64_decode($encrypt_key);
        if (!openssl_private_decrypt($decodedKey, $decryptedKey, $privateKey)) {
            throw new Exception('RSA 解密 DES 秘钥失败');
        }

        // DES 解密业务数据
        $decodedSealData = base64_decode($seal_data);
        $raw = openssl_decrypt($decodedSealData, 'DES-ECB', $decryptedKey, OPENSSL_RAW_DATA);
        if ($raw === false) {
            throw new Exception('DES 解密业务数据失败');
        }

        // 验签
        $signature = base64_decode($sign_data);
        $verify = openssl_verify($raw, $signature, $publicKey, OPENSSL_ALGO_SHA1);
        if ($verify !== 1) {
            throw new Exception('验签不通过!');
        }

        return $raw;
    }

    /**
     * 获取公钥
     *
     * @param string $key
     * @return resource
     * @throws Exception
     */
    public static function getPublicKey($key) {
        $decodedKey = base64_decode($key);
        $publicKey = openssl_get_publickey($decodedKey);
        if ($publicKey === false) {
            throw new Exception('获取公钥失败');
        }
        return $publicKey;
    }

    /**
     * 获取私钥
     *
     * @param string $key
     * @return resource
     * @throws Exception
     */
    public static function getPrivateKey($key) {
        $decodedKey = base64_decode($key);
        $privateKey = openssl_get_privatekey($decodedKey);
        if ($privateKey === false) {
            throw new Exception('获取私钥失败');
        }
        return $privateKey;
    }
}

// 示例用法
try {
    $desKey = SignUtils::genDESKey();
    $publicKey = SignUtils::getPublicKey('你的公钥字符串');
    $privateKey = SignUtils::getPrivateKey('你的私钥字符串');

    $data = '需要加密的数据';
    $encryptedData = SignUtils::encrypt($data, $desKey, $publicKey, $privateKey);

    $decryptedData = SignUtils::decrypt(
        $encryptedData['encrypt_key'],
        $encryptedData['seal_data'],
        $encryptedData['sign_data'],
        $privateKey,
        $publicKey
    );

    echo '解密后的数据: ' . $decryptedData;
} catch (Exception $e) {
    echo '错误: ' . $e->getMessage();
}
?>
 类似资料:
  • 各位大佬下午好,请问要怎么通过bat文件处理txt的文本内容。 现在的情况是我通过notepad++的文本工具处理txt文件内容。 以下是我的手动操作步骤。 1、我通过正则把 txt中的文本每行 字数进行限制代码如下: 2、然后继续通过替换,把txt文本中的“,。!” 等内容替换为空。 3、然后在移除空行。 4、至此完成一个txt文档的处理工程 每天要重复处理几百个txt文档,请问,怎么批量操作以

  • 语言:PHP 服务器:宝塔面板 NGINX 文件位置:/www/wwwroot/xxx.com/upload/txt/《官梯》作者:钓人的鱼.txt PHP代码: BT面板网站NGINX配置文件: 访问网站: xxx.com/index.php?index-txtdown 能进入到这个函数里面,但是实现不了下载。 提示: 无法访问此网站网址为 https://www.xxx.com/index.p

  • Project V 提供了多种方式进行交流。 Project V 团队支持中文和英文,请选择你所熟悉的语言来提问,以避免一些不必要的误会。管理员会以问题发起者使用的语言来回复;如果提问者使用了其它的语言,则以英文回复。 Github Issue 我们使用几个不同的仓库进行不同类型的讨论。 代码问题 仅用于讨论 V2Ray 的代码问题,比如 bug。 未来计划 常规讨论 Telegram 讨论组 P

  • 校验者: @片刻 翻译者: @X 项目邮件列表 如果您在使用 scikit 的过程中发现错误或者需要在说明文档中澄清的内容,可以随时通过 Mailing List 进行咨询。 机器学习从业者的 Q&A 社区 <colgroup><col class="field-name"> <col class="field-body"></colgroup> | Quora.com: | Quora有一个和机

  • 这串代码后 这个sym的变量我该怎么修改

  • 销帮帮CRM,可对客户的整个生命周期进行管理,全面满足企业协同办公、客户管理、行为管理、过程管控、数据统计等需求,从而提升企业运营效率并实现销售业绩快速增长。 管理员引导 开通销帮帮CRM ● 先注册钉钉,后在钉钉内开通销帮帮CRM 下载钉钉,按流程注册 打开钉钉应用中心 进入销帮帮CRM,点击开通 可见范围设置 ● 设置员工可见范围内后,其钉钉工作台会显示销帮帮CRM应用 进入钉钉应用中心,点击

  • 请大佬帮忙把一段之前golang实现的并发读写代码用rust实现

  • 面试官很好,回答后都有反馈,而且性格很好,非常好的一次体验,是我自己太菜了。 30min 说一下rpc 说一zookeeper的一致性算法 通信协议 七层模型 常见协议的作用 TCP拆包和粘包 netty的线程模型 jvm的类加载过程 双亲委派,破坏双亲委派的方法,以及原因 数据库常用的两种引擎的区别 分布式事务,两阶段协议和三阶段协议 项目是否有合作经验,出现问题怎么解决 手撕算法题,递归查询数