Closed yhhhhh closed 1 month ago
格式的问题,看代码签名的是 hex, 加密的用base64 PHP代码生成的 签名是 base64的 ; 加密返回的是 hex, java中前面有个04, 请加个04 , bin2hex(base64_decode($sm2->doSign( $document, $privateKey, $userId))) .'|+|' base64_encode(hex2bin('04'. $sm2->doEncrypt($document1, $publicKey))) , 至于参数是什么格式请按你们相关的文档操作
@lpilp 改了一下加密的格式, 签名是生成的hex格式,还是验签失败 $encrypt = base64_encode(hex2bin('04'. $sm2->doEncrypt(base64_encode($data), $this->public_key))); $sign = $sm2->doSign( $encrypt, $this->private_key);
对方给的demo种的加密后内容: BNavgmldTe4IgFufjkGY4vpR8lexkeqjcvPRPeapr2jDMcSx1d+fWIvsC+QCMQvqhP4mXfl8RTOiCJQortbEKjEkX4bBJKYMUHbN2CYf3oKWPaOp54WiFG/WUzme/IPAMrhlirw4ytgGZTv3i3/hJBMxeXaXFttDMajK9cimfc462qOA+zk7Jv9azzxbtwRdcVZfYw78KbdNl/u9307pBKlqN9w3vUt7bB0q4/dIhxVllu3l+pljgRn+be0tIuoZFW6b6HMt3YssVegh7qPzLYNFEOHXdAQN/3IMGm0cIqL3SnJ0iBMmT7reAOnqe+UC/pRHjWEvFdrcGzVHw8Ce7GOrEcZV2dmODTHxbvPyBqdnZLJ9+ghK1FWSi9TVX5H8xjLVuDor+TTC+ZAmZeV6INivjpqL64SYm5Bs82vH8MMPfwNmTaNaf8Qm/kwRMGDdYX216f0GEXJVyGyL9129rdwnEN6JtIMEz7HN2hHPUcl0lzJXH3Ds6xyj/2LcbajWBisugtjgsX5fm2pR/KAhYj6Ft1UYfIsAuFnDHSnZmRfmbeQl+QLZdZMP9ioYi/cl/TkO90L8VykGK/A15+3Xpy6vpekW5BMFGLx1wLp1IRhhvwT7HGSXpa5NEkP1uopQNzNYXIpgbN4F3ErgvIExsOqquit+ 尝试了下是先hex2bin后base64_encode
加密: BOJ8N4DnBpvacIKiOkidd1h84wlYPtmSU/ZuHZgz7RodC1zobcZxTpl0zyWFiROdexhV6Mn6LywRde4SOpWiPptUtYBzyrQG2/3ipb/CJJemWM4HEhfQ4+7BKQdNU9N+OA8w85NI8/E42b17CWuG1twiz/56z+riE80PGMzM7ZG+3QaJDIbRdnkGGjtgMOm+keFIVtJAVMxYE3ff/9g10m5C++TWvq2ryimNiGL4lRJQSOEFt/BhwYaSlRxm9t4thbo2iASQxdrtSoCeSQraGophDTcmwiHQvN596FYCUFsObJANzCdS2HqBzmDN6sgG/ZIIyguqqcOi7f2xylVk4M+ByNV0upvaHucotVOQpAArFC6N/C0WhvOxJKqNBIs2ynMhWaQc8BFQ4Nktm809J6DZaEEOLVAtSuyJqq9aSAlH4r5eHdIC5UNgZ5OxvFgoE4pdHEy+B/kn8EIYV+0gsqSWxCdM5szf6eZy5TchEMgvV2jJI2nesz/R1TzSRjZ4pa4aL5Orfa+Co3rhpYjFO2OWJ4ZshTz/dgsE4iGFuxhBQSo64uYd4wK8bS2nCBUBy76p0MY67/u2GlohRwImFqflPz8200JzXQYnFKCbbzRfc0+2EdULvNRUmPGoeC6EJn4Y5gtrs+pISI834yEnR7eC2eDG2XPVa9tSX/sfL/LjgM3DxZt2+/3X/EqwynTFHPE0LXz9eeC8k0Nk0MvI8cQ4h30MQIHF93yVW6iIqpitCvn7iwvWyn+OcwONyCZw0pD8dnE8DDgy5HAGnw==
签名: 3045022100bd925f7c8169379bcb8abb45b41f456376efa8731f1d9dc9f14a0ab20bfda740022011e0d77f8b4b0a5c2e0b8f6e929aed0d5259254eb75827bcded79d0bfd6e5791
私钥:94CF3533121E7EC817xxxxxxxxxxxxxxxxxxxxxxxxxxFEFE04D9B71EDA5C63663DC 公钥:4EBC4F2A6C00FC265CD29EBA99084742A45085E23577949AFFDD609152F9B8BEE93A4A8F400102DF74452DDDEF478BB9678A6A90A92E6EA859B618A2BB975EDE
先单独测试下签名吧,用PHP签名,java 验签名, 看了下代码用的 使用 https://github.com/ZZMarquis/gmhelper 封装的 BC库的SM2, 这个库试过与PHP的这个库是可以互相签名的, 1 一样一样的试,先试下签名是否互认 ,就简单的签名如“hello”之类的 2 再试加解密 都可以再结合测试,中间的 要加密与签名的数据有点多,可能这里有点问题
就是那个格式问题,请求成功了,也解密成功了,感谢大佬 @lpilp
数据进行SM2加密、加签后请求JAVA那边不成功 报错:验签失败
JAVA的参考demo
package com.psbc.pay.demo.service.impl;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.psbc.pay.demo.service.HttpService; import com.psbc.pay.demo.service.PaymentService; import com.psbc.pay.demo.util.BCECUtils; import com.psbc.pay.demo.util.FileUtils; import com.psbc.pay.demo.util.SM2Utils; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey; import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; import org.bouncycastle.pqc.math.linearalgebra.ByteUtils; import org.bouncycastle.util.encoders.Base64; import org.joda.time.DateTime; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.RequestBody;
import javax.annotation.Resource; import java.math.BigDecimal; import java.nio.charset.StandardCharsets; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap;
@Service @Slf4j public class PaymentServiceImpl implements PaymentService { // 渠道单位私钥 private final static ConcurrentMap<String, BCECPrivateKey> PRI_KEY_PARAMS = new ConcurrentHashMap<>(); // 缴费平台公钥 private final static ConcurrentMap<String, BCECPublicKey> PUB_KEY_PARAMS = new ConcurrentHashMap<>();
}
SM2Utils代码
package com.psbc.pay.demo.util;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.engines.SM2Engine; import org.bouncycastle.crypto.engines.SM2Engine.Mode; import org.bouncycastle.crypto.params.ECDomainParameters; import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.ParametersWithID; import org.bouncycastle.crypto.params.ParametersWithRandom; import org.bouncycastle.crypto.signers.SM2Signer; import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey; import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.math.ec.custom.gm.SM2P256V1Curve;
import java.math.BigInteger; import java.security.SecureRandom;
/**
*/ public final class SM2Utils { /**
private static final SM2P256V1Curve CURVE = new SM2P256V1Curve(); private final static BigInteger SM2_ECC_N = CURVE.getOrder(); private final static BigInteger SM2_ECC_H = CURVE.getCofactor();
private final static BigInteger SM2_ECC_GX = new BigInteger(SM2_ECC_GX_VAL, 16); private final static BigInteger SM2_ECC_GY = new BigInteger(SM2_ECC_GY_VAL, 16);
private static final ECPoint G_POINT = CURVE.createPoint(SM2_ECC_GX, SM2_ECC_GY); private static final ECDomainParameters DOMAIN_PARAMS = new ECDomainParameters(CURVE, G_POINT, SM2_ECC_N, SM2_ECC_H); /**
private SM2Utils() { }
/**
/**
/**
/**
/**
/**
/**
/**
/**
/**
/**
/**
/**
/**
/**
/**
/**