Delphi / 算法 · 2024年8月12日

国密算法SM2加密及解密

引用CnSM2.Pas;注意一下该单元的版本; 需要使用 2024.01.12 V2.3及以上的版本;

可以从CnPack分离出的算法包中获得,下载地址:https://gitee.com/cnpack/cncrypto

代码引用比较简单(Delphi XE10); 老版本的字符串转Bytes,特别是字符集的问题,要麻烦一些~

加密

  ///AStr:需要加密的字符串   AKey:公密钥
  function SelfEncryptData(AStr : string; AKey : string):string;
  var
    _SM2PublicKey : TCnSM2PublicKey;
    _Bytes_Src, _Bytes_Result : TBytes;
  begin
    Result := '';
    _SM2PublicKey := TCnSM2PublicKey.Create;
    _SM2 := TCnSM2.Create(ctSM2);
    try
      _Bytes_Src := TEncoding.UTF8.GetBytes(AStr);
      _SM2PublicKey.SetHex(AKey);
      _Bytes_Result := CnSM2EncryptData(_Bytes_Src,
                                        _SM2PublicKey
                                       );
      Result := BytesToHexString(_Bytes_Result);
    finally
      if Assigned(_SM2PublicKey) then FreeAndNil(_SM2PublicKey);
    end;
  end;
Pascal

解密

  ///AStr:需要解密的字符串   AKey:私密钥
  function SelfDecryptData(AStr : string; AKey : string):string;
  var
    _SM2PrivateKey : TCnSM2PrivateKey;
    _Bytes_Src, _Bytes_Result : TBytes;
  begin
    Result := '';
    _SM2PrivateKey := TCnSM2PrivateKey.Create;
    try
      _Bytes_Src :=  StringHexToBytes(AStr);
      _SM2PrivateKey.SetHex(AKey);
      _Bytes_Result := CnSM2DecryptData(_Bytes_Src,
                                        _SM2PrivateKey
                                       );
      Result := StringOf(_Bytes_Result);
    finally
      if Assigned(_SM2PrivateKey) then FreeAndNil(_SM2PrivateKey);
    end;
  end;
Pascal

之前使用 CnSM2.pas 2023.03.25 V2.0版本时,会偶尔出现一次加密后的数据解密失败的问题;对应修复版本是 2023.04.10 V2.1 修正部分坐标值较小的情况下的加解密对齐问题;原因是:可能是某些情况下,公私钥或加密的随机数第一个字节是00,旧版本将其转换成二进制数据时把这个00省掉了导致数据对齐出了问题,新版本补上了00就修掉了。

验证地址: 在线SM2加密解密,生成公钥/私钥对工具- (config.net.cn)