1

RSAを使用してデータを暗号化/復号化すると、デルファイではうまく機能しますが、他のプログラムで使用すると機能しないようです。

サーバー側でgolang 1.5を使用していますが、EncryptOAEP/DecryptOAEP、EncryptPKCS1v15/DecryptPKCS1v15を使用すると、これらのペア機能はすべて良好です。

これらすべてをまとめようとすると、お互いを認識できず、さまざまな種類の組み合わせを試してみましたが、うまく機能します。

1.Delphi xe6 2.lockbox リリース 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側のいくつかのコード(ロックボックスをインストールしていないため、すべてのソースをプロジェクトに挿入します) .

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

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 ) を実装します。このアルゴリズムは、ハッシュ関数とマスク生成関数の選択によってパラメーター化されます。2 つの RSA コーデックのハッシュ関数またはマスク生成関数が異なる場合、それらは相互運用できません。

LB3 のハッシュ関数とマスク生成関数は、ユニット TPLB3.RSA_Primitives のプロシージャ MGF1() にあり、SHA-1 に基づいています。相互運用性の可能性があるかどうかを調べるために、goLang が使用するハッシュおよびマスク生成関数を調べる必要があります。この標準は (LB3 で採用された) 推奨事項を示していますが、標準化されたものはありません。

それに加えて、goLang リストから、goLang がキーを PEM 形式でエンコードしているように見えます。LB3 のネイティブ RSA は PEM 形式を使用しません。

相互運用性を最大限に高めるには、ネイティブ RSA コーデックの代わりに LB の OpenSSL コンポーネントを試してください。

Delphi to Delphi にとって、LB3 は優れた暗号化ライブラリです。非常に柔軟で、モジュール化されており、多くの暗号化とブロックチェーン方式があり、公開された広範な単体テストのセットで私が知っている唯一の FOSS ライブラリです。しかし、その大きな弱点は相互運用性です。他の言語またはシステム間の相互運用性が重要な場合は、おそらく別のライブラリを選択する必要があります。

于 2015-11-23T01:07:03.027 に答える