在项目中,经常会遇到接口要求进行验签的动作;SM2签名算法属于非对称密钥算法;需要使用公钥进行验签;JAVA平台生成的公钥很多是压缩公钥(03开头的16进制字符串),需要在平台数据回应时使用公钥进行验签,以保证数据的安全性;
采用CnPack组织开发的Cnvcl包中的密钥算法单元 CnSM2.Pas
uses
CnSM2;
function VerifySign(AID, APublicKey, ASrc, ASign : string):Boolean;
var
_SM2Ecc : TCnSM2;
_SM2PublicKey : TCnSM2PublicKey;
_SM2Signature : TCnSM2Signature;
_Bytes : TBytes;
_sStr : string;
begin
Result := False;
_SM2PublicKey := TCnSM2PublicKey.Create;
_SM2Signature := TCnSM2Signature.Create;
_SM2Ecc := TCnSM2.Create;
try
try
//将签名原文赋值给数组_Bytes
setlength(_Bytes, Length(ASrc));
Move(ASrc[1], _Bytes[0], Length(ASrc));
//将SM2的签名赋值给_SM2Signature
_SM2Signature.SetAsn1Hex(ASign);
//加载压缩公钥(03开头),需要额外传入椭圆曲线TCnSM2;如果是普通公钥(04开头),则不需要传入椭圆曲线TCnSM2
_SM2PublicKey.SetHex(trim('036392c9db2dc1c1e24ab1aac7591a0b680de18e50a2e8bace829278c97b12100d'), _SM2Ecc);
//验证签名
if CnSM2.CnSM2VerifyData(AID, //'1111111111111111',
_Bytes,
_SM2Signature,
_SM2PublicKey,
nil) then
begin
Result := True;
end
else
begin
//记录日志
AddLog(Format('VerifySign 签名验证 - %s',['FAIL']) ,llMessage);
end;
except
on E:Exception do
begin
//记录日志
AddLog(Format('VerifySign Err - %s',[E.Message]) ,llAlert);
end;
end;
finally
if Assigned(_SM2PublicKey) then FreeAndNil(_SM2PublicKey);
if Assigned(_SM2Signature) then FreeAndNil(_SM2Signature);
if Assigned(_SM2Ecc) then FreeAndNil(_SM2Ecc);
end;
end;
Pascal