【问题标题】:RSA encrypt with public key and LockBox3使用公钥和 LockBox3 进行 RSA 加密
【发布时间】:2019-08-06 05:52:55
【问题描述】:

我使用 Delphi XE 和 Lockbox3.5,我想加密一个字符串,该字符串具有由支付网关提供的需要操作的公钥,公钥类似于: -----开始公钥----- 这里的工作人员 -----结束公钥----- 我无法使 RSA 编解码器读取此公钥,我的代码如下:

var
 Ciphertext: string;
 ms: TStream;
begin
 ms := TFileStream.Create('C:\PubKey.txt', fmOpenRead);
 ms.Seek(0, soFromBeginning);
 cdcRSA.StreamCipherId := RSA_ProgId;
 cdcRSA.ChainModeId := RSA_ProgId;
 Signatory1.LoadKeysFromStream(ms, [partPublic]);
 cdcRSA.EncryptAnsiString('WORDSOMEWORDSOME', Ciphertext);
 Memo1.Lines.Add(Ciphertext);
end;

Codec cdcRA 链接到 CryptoLibrary,密码为(RSA 公钥加密系统 *),链接模式为空,但此代码失败并出现内存不足错误。 感谢您的任何提示..

演示中的以下代码也不起作用,有人可以提供一个使用 RSA 和公钥加密字符串的示例吗? :

procedure TForm1.btnRSAClick(Sender: TObject);
var
 sKey, Ciphertext: string;
 ss: TStringStream;
 Key: TSymetricKey;
begin
 sKey := '-----BEGIN PUBLIC KEY-----' +
         'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDlAVd8PUhIiuA00vlUZYm0xrk+' +
         'UgyZxwWZSrysOJWk0POGJ91hUUqr659mBA7bg0i07Y4T+FYdA4iuvg5bT2aSMAGl' +
         'To3GRKvwX8RAnimQQNqkqDk3nf20OiEygwWDQr72fWzKLtuoo7Rd5onrXEp1qM3o' +
         'ywRq5Mwk4dHPX1F5EwIDAQAB' +
         '-----END PUBLIC KEY-----';

 ss := TStringStream.Create(sKey);  ss.Seek(0,soFromBeginning);
 Base64_to_stream(skey, ss);
 cdcRSA.Reset;
 cdcRSA.StreamCipherId := 'native.RSA';
 cdcRSA.ChainModeId:= 'native.CBC';
 cdcRSA.AsymetricKeySizeInBits := 1024;
 key := cdcRSA.Asymetric_Engine.CreateFromStream(ss, [partPublic]); // error out of memory
 cdcRSA.InitFromKey(key);  
 cdcRSA.EncryptString('WORDSOMEWORDSOME', Ciphertext, TEncoding.UTF8);
 Memo1.Lines.Add(Ciphertext);
end;

【问题讨论】:

  • 这个函数多久调用一次?我问的原因是它创建了一个 TFileStream 但没有释放它,导致内存泄漏。
  • 第一次调用函数时发生错误,我添加了释放相同错误的流,它在调用签名组件的函数 LoadKeysFromStream 时引发..

标签: delphi rsa


【解决方案1】:

问题可能在于释放 ms 变量 - TFileStream - 您创建的:

var
 Ciphertext: string;
 ms: TStream;
begin
 ms := TFileStream.Create('C:\PubKey.txt', fmOpenRead);
 try
   ms.Seek(0, soFromBeginning);
   cdcRSA.StreamCipherId := RSA_ProgId;
   cdcRSA.ChainModeId := RSA_ProgId;
   Signatory1.LoadKeysFromStream(ms, [partPublic]);
 finally
   ms.Free;
 end;
 cdcRSA.EncryptAnsiString('WORDSOMEWORDSOME', Ciphertext);
 Memo1.Lines.Add(Ciphertext);
end;

【讨论】:

  • 错误在这一行:Signatory1.LoadKeysFromStream(ms, [partPublic]);即使在释放流之后,错误也是一样的..
【解决方案2】:

密钥文件是一个文本文件,包含一系列行。每一行 在文件中必须不超过 72 8 位字节,不包括行 终止字符。

您的硬编码字符串只有一行 长度为 358 加上 BEGIN /END 行

我们看不到C:\PubKey.txt的内容。文件看起来一样吗?

在末尾添加<CR><LF>

sKey := '-----BEGIN PUBLIC KEY-----'#13#10 +
         'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDlAVd8PUhIiuA00vlUZYm0xrk+'#13#10 +
         'UgyZxwWZSrysOJWk0POGJ91hUUqr659mBA7bg0i07Y4T+FYdA4iuvg5bT2aSMAGl'#13#10 +
         'To3GRKvwX8RAnimQQNqkqDk3nf20OiEygwWDQr72fWzKLtuoo7Rd5onrXEp1qM3o'#13#10 +
         'ywRq5Mwk4dHPX1F5EwIDAQAB'#13#10 +
         '-----END PUBLIC KEY-----';

另请阅读差异...

Differences between BEGIN RSA PUBLIC KEY and BEGIN PUBLIC KEY

有线条

ss := TStringStream.Create(sKey);  ss.Seek(0,soFromBeginning);
 Base64_to_stream(skey, ss);

您使用包含的行 BEGIN ....END .... 执行 Base64_to_stream(skey, ss)

应该是

-----BEGIN PUBLIC KEY-----
BASE64 ENCODED DATA
-----END PUBLIC KEY-----

sKeyBEG := '-----BEGIN PUBLIC KEY-----'#13#10;

sKey := 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDlAVd8PUhIiuA00vlUZYm0xrk+' +
        'UgyZxwWZSrysOJWk0POGJ91hUUqr659mBA7bg0i07Y4T+FYdA4iuvg5bT2aSMAGl' +
        'To3GRKvwX8RAnimQQNqkqDk3nf20OiEygwWDQr72fWzKLtuoo7Rd5onrXEp1qM3o' +
        'ywRq5Mwk4dHPX1F5EwIDAQAB';

sKeyEND := #13#10'-----END PUBLIC KEY-----';

本质上,PEM 文件只是 DER 的 base64 编码版本 编码数据。为了从外面区分是什么 数据在 DER 编码字符串中,存在页眉和页脚 围绕数据

如果要加载带有页眉和页脚的密钥文本文件,则需要找到一种方法将密钥与 key.txt 文件分开。 这并不难。

无论如何,Base64_to_stream(skey, ss) 只能应用于键,而不能应用于周围的文本。

【讨论】:

    猜你喜欢
    • 2011-08-16
    • 2012-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-23
    • 2011-11-07
    • 1970-01-01
    相关资源
    最近更新 更多