导航:
论坛 -> DELPHI技术
斑竹:liumazi,sephil
作者:
2024/1/29 21:10:10
标题:
加入我的收藏
楼主:
求:delphi 7 SM2采用C1C3C2模式,签名、验证; SM4加密、SM4解密;的源代码+例子
----------------------------------------------
-
作者:
2024/1/29 21:16:12
1楼:
CnPack组件包cnvcl有。 https://github.com/cnpack/cnvcl.git SM2的例子见: cnvcl/Example/VCL/SM2 SM4的例子见: cnvcl/Example/VCL/Crypto
----------------------------------------------
欢迎使用CnPack IDE Wizards http://www.cnpack.org/
作者:
2024/1/29 21:26:32
2楼:
非常感谢 cnpack; 这个网站太难打开。
----------------------------------------------
-
作者:
2024/1/30 10:24:02
3楼:
这个网址https: //github.com/cnpack/cnvcl.git 这个网址昨天到现在都都打不开,移 动、电 信 都试过了。
----------------------------------------------
-
作者:
2024/1/30 10:32:25
4楼:
貌似近期github的新加坡微软云的IP被封了导致国内没法访问,得换DNS。 我们在国内也有镜像: https://gitee.com/cnpack/cnvcl
----------------------------------------------
欢迎使用CnPack IDE Wizards http://www.cnpack.org/
作者:
2024/1/30 12:11:31
5楼:
非常感谢 CnPack! 这个地址有下载。 一下子还没弄明白 怎么使用32位私密 ,SM2采用C1C3C2模式 ,对字符串进行签名。 能给个例子吗?
----------------------------------------------
-
作者:
2024/1/30 13:37:16
6楼:
cnvcl/Example/VCL/SM2的例子看了吧? 首先是公私钥,要确定如何加载,是pem格式的文件中加载,还是设置十六进制、还是设置Base64 其次是签名,字符串要确定通过何种编码转换成被签名内容,一般是UTF8。 C1C3C2和C1C2C3模式,CnSM2都支持,具体可以看看例子中的 btnSM2SignFileClick函数,那是针对文件内容签名的,内部把文件加载成了TBytes,你照着改改把字符串通过UTF8编码转成TBytes去签名就行。
----------------------------------------------
欢迎使用CnPack IDE Wizards http://www.cnpack.org/
作者:
2024/1/30 13:39:39
7楼:
不对,说混了,C1C2C3和C1C3C2是SM2的内容加解密模式,和签名验签无关。 “32位私密”?是32字节私钥吧,SM2的私钥是32字节也就是256位的。
----------------------------------------------
欢迎使用CnPack IDE Wizards http://www.cnpack.org/
作者:
2024/1/30 14:41:15
8楼:
CnPack您好! 非常感谢! 签名内容是字符串不是文件;比如: secretKey:="12931cd56508400898f9ff40b7c2f1a7"; Str:="accessKey=aaa&clientPublicKey=ccc&value=Hello World!"; 采用SM2私钥secretKey 对Str进行签名
----------------------------------------------
-
作者:
2024/1/30 18:14:41
9楼:
请教一下:这里的【签名】是一个什么概念?比如楼上提到的对一个字符串签名,是否就是拿自己的私钥去加密这个字符串?--- 暂时不讨论 UTF8 或者 BASE64 之类的编码。
----------------------------------------------
-
作者:
2024/1/30 20:41:30
10楼:
别的私匙,加密后post 回去对方有公匙。
----------------------------------------------
-
作者:
2024/1/30 22:26:26
11楼:
帮帮忙,SM2私钥签名,指导一下,谢谢
----------------------------------------------
-
作者:
2024/1/31 0:08:01
12楼:
签名不是加密,两个概念截然不同。 加密是用私钥对内容加密,密文不可识别,只能够被私钥对应的公钥解密还原。 签名则是针对特定明文,用SM2公私钥结合特定的杂凑算法SM3等,计算出其摘要值作为签名串。明文本身仍是明文,可读。 签名串可以用公钥验证,验证通过说明该签名是拥有该公钥对应私钥的人签发的。
----------------------------------------------
欢迎使用CnPack IDE Wizards http://www.cnpack.org/
作者:
2024/1/31 1:17:23
13楼:
多谢 cnpack。这个解释清晰明了。
----------------------------------------------
-
作者:
2024/1/31 22:03:50
14楼:
谁方便帮助做一个开个价,好吗?
----------------------------------------------
-
作者:
2024/1/31 22:11:33
15楼:
对方使用java 我不会 import cn.hutool.core.util.HexUtil; import cn.hutool.crypto.BCUtil; import cn.hutool.crypto.ECKeyUtil; import cn.hutool.crypto.SmUtil; import cn.hutool.crypto.asymmetric.KeyType; import cn.hutool.crypto.asymmetric.SM2; import org.bouncycastle.asn1.gm.GMNamedCurves; import org.bouncycastle.asn1.x9.X9ECParameters; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.engines.SM2Engine; import org.bouncycastle.crypto.params.*; import org.bouncycastle.crypto.signers.PlainDSAEncoding; import org.bouncycastle.crypto.signers.SM2Signer; import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; import org.bouncycastle.util.Strings; import org.bouncycastle.util.encoders.Hex; import java.math.BigInteger; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.HashMap; import java.util.Map; public class SM2Utils { //生成秘钥对 public static Map<String,String> createSM2Key(){ SM2 sm2= SmUtil.sm2(); sm2.setMode(SM2Engine.Mode.C1C3C2); String privateKey= HexUtil.encodeHexStr(BCUtil.encodeECPrivateKey(sm2.getPrivateKey())); String publicKey = HexUtil.encodeHexStr(((BCECPublicKey) sm2.getPublicKey()).getQ().getEncoded(false)); Map<String,String> keys=new HashMap<>(); keys.put(privateKey,publicKey); return keys; } //加密 public static String encrypt(String publicKey, String data){ String publicKeyTmp = publicKey; if (publicKey.length() == 130) { //这里需要去掉开始第一个字节 第一个字节表示标记 publicKeyTmp = publicKey.substring(2); } String xhex = publicKeyTmp.substring(0, 64); String yhex = publicKeyTmp.substring(64, 128); ECPublicKeyParameters ecPublicKeyParameters = BCUtil.toSm2Params(xhex, yhex); //创建sm2 对象 SM2 sm2 = new SM2(null, ecPublicKeyParameters); sm2.usePlainEncoding(); sm2.setMode(SM2Engine.Mode.C1C3C2); String hex = sm2.encryptHex(data, KeyType.PublicKey).substring(2); return hex; } //解密 public static String decrypt(String privateKey, String data){ //ECKeyUtil.toSm2PrivateParams() SM2 sm2 = new SM2(ECKeyUtil.toSm2PrivateParams(privateKey), null); sm2.setMode(SM2Engine.Mode.C1C3C2); sm2.setEncoding(new PlainDSAEncoding()); if (!data.startsWith("04")) { data = "04"+data; } String encryptStr = sm2.decryptStr(data, KeyType.PrivateKey); return encryptStr; } /** * 私钥签名 DER * @param privateKey 私钥 * @param content 待签名内容 * @return */ public static String sign4Der(String privateKey, String content) throws CryptoException { //待签名内容转为字节数组 byte[] message = content.getBytes(); //获取一条SM2曲线参数 X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1"); //构造domain参数 ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN()); BigInteger privateKeyD = new BigInteger(privateKey, 16); ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters); //创建签名实例 SM2Signer sm2Signer = new SM2Signer(); //初始化签名实例,带上ID,国密的要求,ID默认值:1234567812345678 try { sm2Signer.init(true, new ParametersWithID(new ParametersWithRandom(privateKeyParameters, SecureRandom.getInstance("SHA1PRNG")), Strings.toByteArray("1234567812345678"))); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } sm2Signer.update(message, 0, message.length); //生成签名,签名分为两部分r和s,分别对应索引0和1的数组 byte[] signBytes = sm2Signer.generateSignature(); String sign = Hex.toHexString(signBytes); return sign; } } 参考一下这个。
----------------------------------------------
-
作者:
2024/2/1 10:57:05
16楼:
建议先把需求说清楚,比如你到底需要签名还是加密,公私钥以什么形式存在供加载,生成的签名要什么格式等。 你贴的Java代码,字面上就是SM2的加密和签名功能。
----------------------------------------------
欢迎使用CnPack IDE Wizards http://www.cnpack.org/
作者:
2024/2/1 11:13:33
16楼:
我改了个,你看看,就是签名不要公钥吗 function TFormSM2.sign4Der(privateKeystr:string;content:string):string; begin var SignRes := TCnSM2Signature.Create; var PrivateKey := TCnSM2PrivateKey.Create; PrivateKey.SetHex(privateKeystr); var SM2 := TCnSM2.Create(ctSM2); var PublicKey := TCnSM2PublicKey.Create; PublicKey.SetHex(edtSM2PublicKey.text); //签名不要公钥吗 var contentBts:tbytes; contentBts:=tencoding.UTF8.GetBytes(content); if CnSM2SignData('1234567812345678', contentBts, SignRes, PrivateKey, PublicKey, SM2) then begin result := SignRes.ToHex(SM2.BytesCount); end; end;
----------------------------------------------
-
作者:
2024/2/1 11:48:29
17楼:
SM2签名规范是公私钥一起签,但SM2内部可以从私钥推算公钥,因而调用时一般用私钥签就行了。
----------------------------------------------
欢迎使用CnPack IDE Wizards http://www.cnpack.org/
作者:
2024/2/1 15:28:40
18楼:
只要签名 secretKey:="12931cd56508400898f9ff40b7c2f1a7"; Str:="accessKey=aaa&clientPublicKey=ccc&value=Hello World!"; 采用SM2私钥secretKey 对Str进行签名
----------------------------------------------
-
作者:
2024/2/1 15:35:36
19楼:
@ksrsoft 你看对方给的签名函数 sign4Der(String privateKey, String content),只有privateKey
----------------------------------------------
-
作者:
2024/2/1 15:48:23
20楼:
CnSM2SignData这个里面是需要公钥的,下来就不会了,请老大出马
----------------------------------------------
-
作者:
2024/2/1 15:59:27
21楼:
CnSM2SignData的公钥参数可以传nil。代码中的说明如下: function CnSM2SignData(const UserID: AnsiString; PlainData: TBytes; OutSignature: TCnSM2Signature; PrivateKey: TCnSM2PrivateKey; PublicKey: TCnSM2PublicKey = nil; SM2: TCnSM2 = nil; const RandHex: string = ''): Boolean; overload; {* 私钥对字节数组签名,按 GM/T0003.2-2012《SM2椭圆曲线公钥密码算法第2部分:数字签名算法》 中的运算规则,要附上签名者与曲线信息以及公钥的数字摘要。返回签名是否成功 说明:PublicKey 可传 nil,内部将使用 PrivateKey 重新计算出 PublickKey 参与签名}
----------------------------------------------
欢迎使用CnPack IDE Wizards http://www.cnpack.org/
作者:
2024/2/1 16:59:18
22楼:
那就可以搞定了,签名肯定没问题了。
----------------------------------------------
-
作者:
2024/2/1 21:55:00
23楼:
好,那楼主的问题就交给你了。;-)
----------------------------------------------
欢迎使用CnPack IDE Wizards http://www.cnpack.org/
作者:
2024/2/2 13:43:56
24楼:
医保基线版的很多接口都是SM2验签,SM4加密。不过部分省用的SHA之类的(河北)加密的。就用这个可以搞定的。
----------------------------------------------
-
作者:
2024/2/2 14:27:46
25楼:
医保基线版的很多接口都是SM2验签,SM4加密 ,谁写个demo就好了,大家只会抄
----------------------------------------------
长兴波波
作者:
2024/2/2 21:40:05
26楼:
不就是按照各省的接口指引,组织数据,调用加密函数么,成熟得烂市了,没啥抄的了。
----------------------------------------------
-
作者:
2024/2/4 15:33:16
27楼:
@zhoutler 发个签名、验证的例子看看
----------------------------------------------
-
作者:
2024/2/6 0:16:34
28楼:
楼上cnpack大侠 的CnSM2SignData 我试过多次总是服务端验证不通过; 求 delphi SM2签名 例子源码 以下是签名参数 SM2私钥(PrivateKey)(Hex) 字符串 待签内容 (UTU-8 / HEX /Base64 ) SM3杂凑, User ID (签名用UserId,SM2默认值为UTF-8:1234567812345678) DER编解码
----------------------------------------------
-
作者:
2024/2/6 17:29:32
29楼:
DER编解码,是指最终签名出来的内容要用DER编解码?如果是,可以调用TCnSM2Signature的ToAsn1Hex方法或ToAsn1Base64,将签名内容进行DER编码后,转换成十六进制、或Base64输出成字符串。 前三个参数都满足。
----------------------------------------------
欢迎使用CnPack IDE Wizards http://www.cnpack.org/
作者:
2024/2/7 5:51:01
30楼:
CnPACK 非常感谢指导! 但是前几天已经使用ToAsn1Hex或ToAsn1Base64,不知道为干什么无法验证。到这个 https://www.btool.cn/sm2-verify-sign 网站测试也没通过。签名编码比这个网短一些。
----------------------------------------------
-
作者:
2024/2/7 13:46:49
31楼:
奇怪,我上这个网站上测了一下,它签出来的,CnSM2例子是能验证成功的,我们签出来的,它也能验证成功。 我看了一下你说的“签名编码比这个网短一些”的情况,是ASN1排列过程中的去前导0的不同导致的,不影响ASN1的解析和结果。
----------------------------------------------
欢迎使用CnPack IDE Wizards http://www.cnpack.org/
作者:
2024/2/7 14:04:04
32楼:
晕了,我的怎么就不成功能呢,您签到是字符串还是文件?
----------------------------------------------
-
作者:
2024/2/7 14:06:41
33楼:
CnPack 您是怎么签名的,把要签名的字符串保存成文件然后用用你的代码签名。然后把字符串拷贝到那个网站测试?
----------------------------------------------
-
作者:
2024/2/7 14:18:25
34楼:
是的。例子程序运行,切换到第二页,格式选ASN1Hex,而且User Id那一栏清空。 (当然也可以手工填上1234567812345678)
----------------------------------------------
欢迎使用CnPack IDE Wizards http://www.cnpack.org/
作者:
2024/2/7 14:19:36
35楼:
待签名的字符串保存成文件时要注意后面不要多出回车换行空格等内容。
----------------------------------------------
欢迎使用CnPack IDE Wizards http://www.cnpack.org/
作者:
2024/2/7 14:39:42
34楼:
CnPack 我刚刚又去,用CnSM2生成要密钥, 拿CnSM2签出来的去那个网验签 或者 拿那个网站的签出来的给CnSM2验签 都没通过,不知道哪儿出错了。 CnPack 方便给个联系方式好吗?
----------------------------------------------
-
作者:
2024/2/7 15:50:52
36楼:
行,我们的邮箱master@cnpack.org
----------------------------------------------
欢迎使用CnPack IDE Wizards http://www.cnpack.org/
作者:
2024/2/7 16:36:57
37楼:
CnPack 已经给您邮件了,注意查收。
----------------------------------------------
-
作者:
2024/2/7 16:46:31
38楼:
收到邮件了,看出几个问题,待沟通。
----------------------------------------------
欢迎使用CnPack IDE Wizards http://www.cnpack.org/
作者:
2024/2/8 12:12:53
39楼:
楼主的代码里主要有四个问题,已解决: 1、公私钥使用时不慎搞反了。 2、待签名内容使用了UTF16编码,和网站上验签的对不上号。 3、网站要求公钥带04前缀,公钥分别X、Y输出时没这前缀,改成直接用ToHex方法才能满足这个要求。 4、待签名内容有汉字时,需用UTF8编码,无则可以用Ansi。
----------------------------------------------
欢迎使用CnPack IDE Wizards http://www.cnpack.org/