Sha1WithRSA签名的问题

为了帮助网友解决“请教Sha1WithRSA签名的问题,急”相关的问题,中国学网通过互联网对“请教Sha1WithRSA签名的问题,急”相关的解决方案进行了整理,用户详细问题包括:我使用的是D2010,openssl是1.0.0.7(其他版本也试过),libeay32.pas是从网上下载的0.9.6b
按照百度搜索的文章所说,在libeay32.pas中添加
procedure EVP_MD_CTX_init(ctx: pEVP_MD_CTX); cdecl;
procedure EVP_MD_CTX_cleanup(ctx: pEVP_MD_CTX); cdecl;
function RSA_sign(rsatype: integer; m: PCharacter; m_length: integer;
    sigbuf: PCharacter; siglen: Cardinal; rsa: pRSA): integer; cdecl;
procedure EVP_MD_CTX_init; external LIBEAY_DLL_NAME;
procedure EVP_MD_CTX_cleanup; external LIBEAY_DLL_NAME;
function RSA_sign; external LIBEAY_DLL_NAME;

key文件是用openssl工具生成的,可是签名却总是报内存错误
以下是详细代码,请做过的给指点以下,





uses
  libeay32, EncdDecd;

function LoadPrivateKey(filename: AnsiString): PEVP_PKEY;
var
  bp: PBIO;
  A, pkey: PEVP_PKEY;
begin
  A := nil;
  bp := BIO_new(BIO_s_file());
  BIO_read_filename(bp, PAnsiChar(filename));
  pkey := PEM_read_bio_PrivateKey(bp, A, nil, NIL);
  BIO_free(bp);
  Result := pkey;
end;

function Sign(filename, msg: AnsiString): string;
var
  ctx: EVP_MD_CTX;
  buf_in: PAnsiChar;
  m_len, outl: cardinal;
  pkey: PEVP_PKEY;
  m, buf_out: array [0 .. 1024] of AnsiChar;
  p: array [0 .. 255] of AnsiChar;
  i: Integer;
begin
  buf_out := '';
  if filename = '' then
  begin
    Result := '';
    Exit;
  end;
  ZeroMemory(@m, SizeOf(m));
  ZeroMemory(@buf_out, SizeOf(buf_out));
  pkey := LoadPrivateKey(filename);
  buf_in := PAnsiChar(msg);
  EVP_MD_CTX_init(@ctx); // 初始化
  EVP_SignInit(@ctx, EVP_sha1());
  EVP_SignUpdate(@ctx, buf_in, Length(buf_in));
  EVP_DigestFinal(@ctx, m, m_len);
  RSA_sign(EVP_sha1()._type, m, m_len, buf_out, outl, pkey.pkey.rsa);  //<---------------此处报错
{
---------------------------
Project1
---------------------------
Access violation at address 67A93071 in module 'libeay32.dll'. Read of address EF96BD97.
---------------------------
确定   
---------------------------
}
  EVP_MD_CTX_cleanup(@ctx);
  Result := EncodeString(StrPas(buf_out));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
OpenSSL_add_all_algorithms;
  Sign('d:\rsa_private_key.pem', '123456');
end;,具体解决方案如下:

解决方案1:
我也弄了2个星期才搞定!首先感谢star1010 提供的2个函数!
第一步:下载indy9 支持ssllib 的2个DLL。CSDN有!
第二步:网上百度libeay32.pas
第三步:修改libeay32.pas,自己添加 procedure EVP_MD_CTX_init(ctx: pEVP_MD_CTX); cdecl;
procedure EVP_MD_CTX_cleanup(ctx: pEVP_MD_CTX); cdecl;
function RSA_sign(len:integer;_m:PCharacter;_m_length:integer; from: PCharacter; _to: pointer; rsa: pRSA): integer; cdecl;
第四步:就是DELPHI代码了:
function LoadPrivateKey(filename:string ): PEVP_PKEY;  
var  
  bp : PBIO  ;  
 A,pkey :PEVP_PKEY ;  
begin  
  a:=nil;  
  bp := BIO_new(BIO_s_file()) ;  
  BIO_read_filename(bp, PChar(filename));  
  pkey := PEM_read_bio_PrivateKey(bp, a, nil,NIL);  
  BIO_free(bp);  
  Result:= pkey;  
end;  
  
function Sign(filename,msg : String):string;  
var  
     ctx : EVP_MD_CTX   ;  
     buf_in:Pchar;  
     m_len,outl :cardinal;  
     pKey : PEVP_PKEY;  
     m,buf_out:array   [0..1024]   of   char;  
     p:array   [0..255]   of   char;  
     i:Integer;  
 begin  
 buf_out:='';  
 if filename='' then  
 begin  
   Result:='';  
   Exit;  
 end;  
  pKey := LoadPrivateKey(filename);  
   buf_in := PChar(msg);  
   EVP_MD_CTX_init(@ctx);            //初始化  
   EVP_SignInit(@ctx,EVP_sha1());    //将需要使用的摘要算法存入ctxl中  
    EVP_SignUpdate(@ctx,buf_in,Length(buf_in));//存入编码值  
   EVP_DigestFinal(@ctx,m,m_len);    //求取编码的长度为m_len摘要值存入m中  
 rSA_sign(EVP_sha1()._type,m,m_len,buf_out,@outl,pkey.pkey.rsa); //64为SHA1的NID  
 EVP_MD_CTX_cleanup(@ctx);  
  
   Result:=EncodeString(StrPas(buf_out)) ;  

出来的结果和淘宝提供的签名工具一致!

一开始我也是报错!你用的是indy几?我用的是9,要下载特定的2个库

解决方案2:
原来是跟openssl动态库有关,换了好多dll,终于找着一个0.9.8的能用,浪费我这么多时间。
非常感谢shadowpj!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是SHA256withRSA签名与验签的Java代码示例: **签名代码:** ``` import java.security.*; import java.util.Base64; public class RSASignatureExample { public static void main(String[] args) throws Exception { String message = "This is a message to be signed."; // Generate key pair KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(2048); KeyPair keyPair = keyGen.generateKeyPair(); // Create a signature object Signature signature = Signature.getInstance("SHA256withRSA"); // Initialize the signature object with the private key PrivateKey privateKey = keyPair.getPrivate(); signature.initSign(privateKey); // Update the signature object with the message signature.update(message.getBytes()); // Sign the message byte[] signatureBytes = signature.sign(); // Print the signature in Base64 encoding System.out.println("Signature: " + Base64.getEncoder().encodeToString(signatureBytes)); } } ``` **验签代码:** ``` import java.security.*; import java.util.Base64; public class RSASignatureExample { public static void main(String[] args) throws Exception { String message = "This is a message to be signed."; String signatureString = "PLl6yBb6IhOv0Jd3k1y/YlR9a3UOx0WJQy6RbbS/3W8mQ2ztcL5x+JShHl6O8gTlJn4wtNQ7Ggz0ZiPwq9SInQf/9d4eG4qSkZCzVgP9U9bQY7jwFVhWXfzqU6l5K8SxyA2pBw+PQs0N2dJQ2Xk9V3tXZP5h+UcMXwLQe/3K7uh2M="; // Generate key pair KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(2048); KeyPair keyPair = keyGen.generateKeyPair(); // Create a signature object Signature signature = Signature.getInstance("SHA256withRSA"); // Initialize the signature object with the public key PublicKey publicKey = keyPair.getPublic(); signature.initVerify(publicKey); // Update the signature object with the message signature.update(message.getBytes()); // Verify the signature boolean verified = signature.verify(Base64.getDecoder().decode(signatureString)); // Print the verification result System.out.println("Signature verified: " + verified); } } ``` 以上代码示例中,我们使用SHA256withRSA算法对一个字符串进行签名和验签。在签名时,我们首先生成了一个RSA密钥对,然后使用私钥对消息进行签名,并打印出Base64编码的签名结果。在验签时,我们使用同样的RSA密钥对和签名算法,使用公钥初始化签名对象,并使用该对象对消息进行验证,最终打印验证结果。需要注意的是,验签时需要将签名结果从Base64编码中解码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值