1

当我使用 RSA 加密/解密数据时,它们在 delphi 中运行良好。但是当我将它们与其他程序一起使用时,它们似乎不起作用。

我在服务器端使用 golang 1.5,当我使用 EncryptOAEP/DecryptOAEP、EncryptPKCS1v15/DecryptPKCS1v15 时,这些对功能都很好。

当我尝试将所有这些放在一起时,它们无法相互识别,我尝试了很多组合,对于它们自己来说,它们工作得很好。

1.Delphi xe6 2.lockbox Release v3.6.3.0 3.部分代码

服务器端的golang

import (
    "errors"    
    "strings"
    "strconv"
    "log"
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
    //"strconv"
    "encoding/base64"
    "encoding/json"
    "bytes"
    //"strings"
)

var privateKey = []byte(`
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDZsfv1qscqYdy4vY+P4e3cAtmvppXQcRvrF1cB4drkv0haU24Y
7m5qYtT52Kr539RdbKKdLAM6s20lWy7+5C0DgacdwYWd/7PeCELyEipZJL07Vro7
Ate8Bfjya+wltGK9+XNUIHiumUKULW4KDx21+1NLAUeJ6PeW+DAkmJWF6QIDAQAB
AoGBAJlNxenTQj6OfCl9FMR2jlMJjtMrtQT9InQEE7m3m7bLHeC+MCJOhmNVBjaM
ZpthDORdxIZ6oCuOf6Z2+Dl35lntGFh5J7S34UP2BWzF1IyyQfySCNexGNHKT1G1
XKQtHmtc2gWWthEg+S6ciIyw2IGrrP2Rke81vYHExPrexf0hAkEA9Izb0MiYsMCB
/jemLJB0Lb3Y/B8xjGjQFFBQT7bmwBVjvZWZVpnMnXi9sWGdgUpxsCuAIROXjZ40
IRZ2C9EouwJBAOPjPvV8Sgw4vaseOqlJvSq/C/pIFx6RVznDGlc8bRg7SgTPpjHG
4G+M3mVgpCX1a/EU1mB+fhiJ2LAZ/pTtY6sCQGaW9NwIWu3DRIVGCSMm0mYh/3X9
DAcwLSJoctiODQ1Fq9rreDE5QfpJnaJdJfsIJNtX1F+L3YceeBXtW0Ynz2MCQBI8
9KP274Is5FkWkUFNKnuKUK4WKOuEXEO+LpR+vIhs7k6WQ8nGDd4/mujoJBr5mkrw
DPwqA3N5TMNDQVGv8gMCQQCaKGJgWYgvo3/milFfImbp+m7/Y3vCptarldXrYQWO
AQjxwc71ZGBFDITYvdgJM1MTqc8xQek1FXn1vfpy2c6O
-----END RSA PRIVATE KEY-----
`)
var publicKey = []byte(`
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZsfv1qscqYdy4vY+P4e3cAtmv
ppXQcRvrF1cB4drkv0haU24Y7m5qYtT52Kr539RdbKKdLAM6s20lWy7+5C0Dgacd
wYWd/7PeCELyEipZJL07Vro7Ate8Bfjya+wltGK9+XNUIHiumUKULW4KDx21+1NL
AUeJ6PeW+DAkmJWF6QIDAQAB
-----END PUBLIC KEY-----
`)
type DebugKeysRPC_Args struct {

}
type DebugKeysRPC_Reply struct {
    PubN        string
    PubE        uint64
    PrvN        string
    PrvD        string
    PrvP        string
    PrvQ        string
    Dp          string
    Dq          string
    Qinv        string
    CRTValues   string
    ID      uint64
    Key     string
    Dest    string  
}

func (t *AccessDB) DebugKeysRPC(args *DebugKeysRPC_Args, reply *DebugKeysRPC_Reply) error { 
    log.Println("DebugKeysRPC")

    if pubN,pubE,PrvN,PrvD,PrvP,PrvQ,Dp,Dq,Qinv,CRTValues,err:=ReadKeyFields(publicKey,privateKey);err==nil{
        log.Println("ok read")
        reply.PubN=base64.StdEncoding.EncodeToString(pubN)
        reply.PubE=uint64(pubE)
        reply.PrvN=base64.StdEncoding.EncodeToString(PrvN)
        reply.PrvD=base64.StdEncoding.EncodeToString(PrvD)
        reply.PrvP=base64.StdEncoding.EncodeToString(PrvP)
        reply.PrvQ=base64.StdEncoding.EncodeToString(PrvQ)
        reply.Dp=base64.StdEncoding.EncodeToString(Dp)
        reply.Dq=base64.StdEncoding.EncodeToString(Dq)
        reply.Qinv=base64.StdEncoding.EncodeToString(Qinv)
        reply.CRTValues=base64.StdEncoding.EncodeToString(CRTValues)
        reply.ID=1
        //origData:=[]byte("abcdefghijklmnopqrstuvwxyz")
        origData:=[]byte("1234567890123456")
        if resultRsa,err:=DbgRasEncryptOAEP(origData,publicKey);err==nil{
        //if resultRsa,err:=RsaEncrypt(origData,publicKey);err==nil{
            log.Printf("resultRsa(%d): % x", len(resultRsa),resultRsa)
            reply.Dest=base64.StdEncoding.EncodeToString(resultRsa)
            if resultRsaP,err:=DbgRsaDecryptOAEP(resultRsa,privateKey);err==nil{
                //log.Printf("RsaDecrypt ok % x", resultRsaP)   
                log.Println("RsaDecrypt ok")
                log.Printf("resultRsaP(%d): %s", len(string(resultRsaP)),string(resultRsaP))
            }else{
                log.Println("RsaDecrypt",err)
            }
        }else{
            log.Println("RsaEncrypt",err)
        }                   
    }else{
        WatchPublicKey(publicKey)
        WatchPrivateKey(privateKey)
        log.Println(err)
    }

    return nil
}

==================================================== ============================= delphi side中的某些代码(我尚未安装Lockbox,我将所有源插入项目) .

==================================================== ==============================

procedure RsaEncrypt( const PublicKey: TStream; const srcStream : TStream;tgtStream:TStream);
var
  Codec : TCodec;
  wasAborted: boolean;
  KeyPair: TAsymetricKeyPair;
  Key: TSymetricKey;
  lib : TCryptographicLibrary;
begin
  Codec := TCodec.Create(Nil);
  lib := TCryptographicLibrary.Create(Nil);
  try
    //0. Reset
    Codec.Reset;
    Codec.CryptoLibrary := lib;
    Codec.ChainModeId := ECB_ProgId;
    Codec.StreamCipherId := 'native.RSA';

    //1. Set the cipher to RSA encryption.
    Codec.StreamCipherId := RSA_ProgId;

    //2. Load our pre-fabricated public key.
    PublicKey.Position := 0;
    Codec.AsymetricKeySizeInBits := 1024;
    Key := Codec.Asymetric_Engine.CreateFromStream(PublicKey, [partPublic]);

    //3. Now set the key.
    Codec.InitFromKey(Key);
    Codec.EncryptStream(srcStream,tgtStream);
  finally
    lib.Free;
    Codec.Free;
  end;
end;

procedure RsaDecrypt( const PrivateKey: TStream; const srcStream : TStream;tgtStream:TStream);
var
  Codec : TCodec;
  wasAborted: boolean;
  KeyPair: TAsymetricKeyPair;
  //Key: TSymetricKey;
  lib : TCryptographicLibrary;
begin
  Codec := TCodec.Create(Nil);
  lib := TCryptographicLibrary.Create(Nil);
  try
   //0. Reset
   Codec.Reset;
   Codec.CryptoLibrary := lib;
   Codec.ChainModeId := ECB_ProgId;
   Codec.StreamCipherId := 'native.RSA';

    //1. Set the cipher to RSA encryption.
    Codec.StreamCipherId := RSA_ProgId;

    //2. Load our pre-fabricated private key.
    PrivateKey.Position := 0;
    Codec.AsymetricKeySizeInBits := 1024;
    KeyPair := Codec.Asymetric_Engine.CreateFromStream(PrivateKey, [partPrivate]);

    //3. Now set the key.
    Codec.InitFromKey(KeyPair);

    Codec.DecryptStream(tgtStream,srcStream);
  finally
    lib.Free;
    Codec.Free;
  end;
end;

procedure Sign(privateKey,srcStream,tgtStream:TMemoryStream);
var
  sign:TSignature;
begin
  try
    sign:=TSignature.Create;
    privateKey.Seek(0,soBeginning);
    sign.m_Signatory.LoadKeysFromStream(privateKey,[partPrivate]);

    sign.m_Signatory.Sign(srcStream,tgtStream);
  finally
    sign.Free;
  end;
end;

function Verify(publicKey,srcStream,tgtStream:TMemoryStream):Boolean;
var
  sign:TSignature;
  vResult:TVerifyResult;
  nDbg:Integer;
begin
  try
    result:=False;
    publicKey.Seek(0,soBeginning);
    srcStream.Seek(0,soBeginning);
    tgtStream.Seek(0,soBeginning);
    sign:=TSignature.Create;
    sign.m_Signatory.LoadKeysFromStream(publicKey,[partPublic]);

    vResult:=sign.m_Signatory.Verify(srcStream,tgtStream);
    if vResult=vPass then
    begin
      nDbg:=0;
      result:=True;
    end
    else if vResult=vFail then
    begin
      nDbg:=1;
    end
    else if vResult=vUserAbort then
      nDbg:=3
    else nDbg:=4;
  finally
    sign.Free;
  end;
end;

procedure readPubKey(pubN:TStream;pubE:TStream);
var
  publicKey:TMemoryStream;
  Codec : TCodec;
  Key: TAsymetricKeyPair;
  lib : TCryptographicLibrary;
begin
  try
    publicKey:=TMemoryStream.Create;

    publicKey.LoadFromFile('e:\public.key');

    Codec := TCodec.Create(Nil);
    lib := TCryptographicLibrary.Create(Nil);
    try
      //0. Reset
      Codec.Reset;
      Codec.CryptoLibrary := lib;
      Codec.ChainModeId := ECB_ProgId;

      //1. Set the cipher to RSA encryption.
      Codec.StreamCipherId := RSA_ProgId;

      //2. Load our pre-fabricated public key.
      PublicKey.Position := 0;
      Codec.AsymetricKeySizeInBits := 1024;
      Key := Codec.Asymetric_Engine.CreateFromStream(publicKey, [partPublic]);
      //pubN.Write(Key.F_RSA_n.Value,sizeof(Key.F_RSA_n.Value));
      //pubE.Write(Key.F_RSA_n.Value,sizeof(Key.F_RSA_e.Value));
      pubN.CopyFrom((TRSAKeyPair(Key)).F_RSA_n.Value.FValue,0);
      pubE.CopyFrom((TRSAKeyPair(Key)).F_RSA_e.Value.FValue,0);
    finally
      lib.Free;
      Codec.Free;
    end;

  finally
    publicKey.Free;
  end;
end;

procedure dbgRsaKeys();
var
  publicKey:TMemoryStream;
  privateKey:TMemoryStream;
  tgtStream:TMemoryStream;
  srcStream:TStringStream;
  src:string;
  rstStream:TStringStream;
  sResult:string;
begin
  publicKey:=TMemoryStream.Create;
  privateKey:=TMemoryStream.Create;
  rstStream:=TStringStream.Create;
  srcStream:=TStringStream.Create;
  tgtStream:=TMemoryStream.Create;
  try
    src:='tell me why,tell me how,tell me where';
    srcStream.WriteString(src);
    srcStream.Seek(0,soBeginning);
    publicKey.LoadFromFile('e:\public.key');
    privateKey.LoadFromFile('e:\private.key');

    RsaEncrypt( PublicKey,srcStream ,tgtStream);

    RsaDecrypt( PrivateKey,tgtStream,rstStream);
    sResult:=rstStream.DataString;
  finally
    publicKey.Free;
    privateKey.Free;
    srcStream.Free;
    tgtStream.Free;
    rstStream.Free;
  end;
end;
procedure TestEncrypt();
var
  publicKey:TMemoryStream;
  srcStream,tgtStream:TMemoryStream;
begin
  try
    publicKey:=TMemoryStream.Create;

    srcStream:=TMemoryStream.Create;
    srcStream.LoadFromFile('e:\scanconfig.txt');
    tgtStream:=TMemoryStream.Create;
    publicKey.LoadFromFile('e:\public.key');

    RsaEncrypt( PublicKey,srcStream ,tgtStream);

    tgtStream.SaveToFile('e:\scanconfig.enc');
  finally
    publicKey.Free;
    srcStream.Free;
    tgtStream.Free;
  end;
end;

procedure TestDecrypt(srcStream:TMemoryStream);
var
  privateKey:TMemoryStream;
  tgtStream:TStringStream;
  sResult:String;
begin
  //dbgRsaKeys();
  privateKey:=TMemoryStream.Create;
  tgtStream:=TStringStream.Create;
  try
    srcStream.Seek(0,soBeginning);
    privateKey.LoadFromFile('e:\private.key');
    RsaDecrypt( privateKey,srcStream,tgtStream);
    sResult:=tgtStream.DataString;
  finally
    privateKey.Free;
    tgtStream.Free;
  end;
end;

==================================================== ===============================

4

1 回答 1

0

TP Lockbox 3 本机 RSA 编解码器实现 RSA/PKCS#1 版本 2.1 ( http://www.ietf.org/rfc/rfc3447.txt )。该算法通过选择散列函数和掩码生成函数来参数化。如果两个 RSA 编解码器具有不同的散列函数或掩码生成函数,它们将无法互操作。

LB3 中的散列函数和掩码生成函数可以在单元 TPLB3.RSA_Primitives 的过程 MGF1() 中找到,并且基于 SHA-1。您必须找出 goLang 使用什么哈希和掩码生成函数来确定是否有机会实现互操作性。该标准给出了建议(被 LB3 采用),但没有一个是标准化的。

除此之外,从您的 goLang 列表中可以看出,goLang 以 PEM 格式对密钥进行编码。LB3 的原生 RSA 不使用 PEM 格式。

为了获得互操作性的最佳机会,请尝试使用 LB 的 OpenSSL 组件而不是本机 RSA 编解码器。

对于 Delphi 到 Delphi,LB3 是一个很棒的密码库。非常灵活、模块化,具有大量密码和块链接方法,并且是我所知道的唯一一个具有已发布且广泛的单元测试集的 FOSS 库。但它最大的弱点是互操作性。如果其他语言或系统之间的互操作性很重要,那么您可能应该选择另一个库。

于 2015-11-23T01:07:03.027 回答