3

ついに Delphi での SRP プロトコルの実装を完了しました! openssl ライブラリを使用して、ハッシュと Bignum を計算します。

最後の実装は複雑ではありません。しかし、私は疑問に思っています:

1) ランダムなペア N, g を使用できます。N 4096 ビットは安全ですか?

2) RFC 5054 のように、K は強力なセッション キーですが、N から 4906 ビットまでの長さは 768 バイトです。では、このセッション キーを AES256 で正しく使用するにはどうすればよいでしょうか?

3) 最後に、私が書いた実装が正常に動作するかどうかをテストする方法はありますか? 私にアドバイスをくれる人はいますか?

まだ最適化されていないことを考慮して、コードを配置します。型 N、G はクラス var である可能性があります。

すべてに前もって感謝します。

type

  TSRP = class
  public
    class procedure CreateVerifierKey( const AIdentity, APassword: TIdBytes; var ASalt, AVerifierKey: TIdBytes );
    class procedure ServerValues( const ASalt, AVerifierKey: TIdBytes; var APrivateValue, APublicValue: TIdBytes );
    class procedure IdentityValues( var APrivateValue, APublicValue: TIdBytes );
    class function ServerKey( const AServerPrivateValue, AServerPublicValue, AVerifierKey, AIdentityPublicValue: TIdBytes ): TIdBytes;
    class function IdentityKey( const AIdentity, APassword, AIdentityPrivateValue, AIdentityPublicValue, ASalt, AServerPublicValue, AVerifierKey: TIdBytes ): TIdBytes;
    class function VerifierMessage( const AUserName: String; const ASalt, AServerPublicValue, AIdentityPublicValue, AKey: TIdBytes ): TIdBytes;
  end;

{ TSRP }

class procedure TSRP.CreateVerifierKey( const AIdentity, APassword: TIdBytes; var ASalt, AVerifierKey: TIdBytes );
var
  N: PBIGNUM;
  G: PBIGNUM;
  S: PBIGNUM;
  X: PBIGNUM;
  V: PBIGNUM;
  C: PBN_CTX;
begin
  S := BIGNUM;
  try
    BN_rand( S, 48, - 1, 0 );
    ASalt := BN_bytes( S );
  finally
    BN_free( S );
  end;
  X := BIGNUM( TIdSha512Hash.Digest( TIdBytes.From( ASalt ).Append( AIdentity ).Append( APassword ) ) );
  N := BIGNUM( TIdBase64.Decode( SRP_NG_4096_N ) );
  G := BIGNUM( [ 5 ] );
  C := BN_CTX_new;
  V := BN_new;
  BN_mod_exp( V, G, X, N, C );
  SetLength( AVerifierKey, TIdSha512Hash.Size );
  AVerifierKey := BN_bytes( V );
  BN_free( X );
  BN_free( N );
  BN_free( G );
  BN_free( V );
  BN_CTX_free( C );
end;

class procedure TSRP.ServerValues( const ASalt, AVerifierKey: TIdBytes; var APrivateValue, APublicValue: TIdBytes );
var
  G: PBIGNUM;
  N: PBIGNUM;
  K: PBIGNUM;
  B: PBIGNUM;
  R: PBIGNUM;
  A: PBIGNUM;
  V: PBIGNUM;
  C: PBN_CTX;
begin
  B := BIGNUM;
  BN_rand( B, 256, - 1, 0 );
  APrivateValue := BN_bytes( B );
  N := BIGNUM( TIdBase64.Decode( SRP_NG_4096_N ) );
  G := BIGNUM( [ 5 ] );
  K := BIGNUM( TIdSha512Hash.Digest( TIdBytes.From( BN_Bytes( N ) ).Append( BN_Bytes( G ) ) ) );
  R := BIGNUM;
  A := BIGNUM;
  V := BIGNUM;
  C := BN_CTX_new;
  BN_mul( R, K, BIGNUM( AVerifierKey ), C );
  BN_mod_exp( A, G, B, N, C );
  BN_add( V, R, A );
  APublicValue := BN_bytes( V );
  BN_free( V );
  BN_free( A );
  BN_free( R );
  BN_free( K );
  BN_free( G );
  BN_free( N );
  BN_free( B );
  BN_CTX_free( C );
end;

class procedure TSRP.IdentityValues( var APrivateValue, APublicValue: TIdBytes );
var
  N: PBIGNUM;
  G: PBIGNUM;
  B: PBIGNUM;
  A: PBIGNUM;
  C: PBN_CTX;
begin
  N := BIGNUM( TIdBase64.Decode( SRP_NG_4096_N ) );
  G := BIGNUM( [ 5 ] );
  B := BIGNUM;
  A := BIGNUM;
  BN_rand( B, 256, - 1, 0 );
  APrivateValue := BN_bytes( B );
  C := BN_CTX_new;
  BN_mod_exp( A, G, B, N, C );
  APublicValue := BN_bytes( A );
  BN_free( B );
  BN_free( A );
  BN_free( G );
  BN_free( N );
  BN_CTX_free( C );
end;

class function TSRP.ServerKey( const AServerPrivateValue, AServerPublicValue, AVerifierKey, AIdentityPublicValue: TIdBytes ): TIdBytes;
var
  N: PBIGNUM;
  G: PBIGNUM;
  A: PBIGNUM;
  B: PBIGNUM;
  U: PBIGNUM;
  V: PBIGNUM;
  T: PBIGNUM;
  J: PBIGNUM;
  R: PBIGNUM;
  C: PBN_CTX;
begin
  N := BIGNUM( TIdBase64.Decode( SRP_NG_4096_N ) );
  G := BIGNUM( [ 5 ] );
  A := BIGNUM( AIdentityPublicValue );
  B := BIGNUM( AServerPrivateValue );
  V := BIGNUM( AVerifierKey );
  U := BIGNUM( TIdSha512Hash.Digest( TIdBytes.From( AIdentityPublicValue ).Append( AServerPublicValue ) ) );
  T := BIGNUM;
  J := BIGNUM;
  R := BIGNUM;
  C := BN_CTX_new;
  BN_mod_exp( T, V, U, N, C );
  BN_mul( J, A, T, C );
  BN_mod_exp( R, J, B, N, C );
  Result := BN_bytes( R );
  BN_free( N );
  BN_free( G );
  BN_free( A );
  BN_free( B );
  BN_free( V );
  BN_free( U );
  BN_free( T );
  BN_free( J );
  BN_free( R );
  BN_CTX_free( C );
end;

class function TSRP.IdentityKey( const AIdentity, APassword, AIdentityPrivateValue, AIdentityPublicValue, ASalt, AServerPublicValue, AVerifierKey: TIdBytes ): TIdBytes;
var
  N: PBIGNUM;
  G: PBIGNUM;
  B: PBIGNUM;
  X: PBIGNUM;
  K: PBIGNUM;
  A: PBIGNUM;
  U: PBIGNUM;
  V: PBIGNUM;
  T: PBIGNUM;
  L: PBIGNUM;
  P: PBIGNUM;
  Q: PBIGNUM;
  R: PBIGNUM;
  C: PBN_CTX;
begin
  N := BIGNUM( TIdBase64.Decode( SRP_NG_4096_N ) );
  G := BIGNUM( [ 5 ] );
  B := BIGNUM( AServerPublicValue );
  X := BIGNUM( TIdSha512Hash.Digest( TIdBytes.From( ASalt ).Append( AIdentity ).Append( APassword ) ) );
  K := BIGNUM( TIdSha512Hash.Digest( BN_bytes( N ).Append( BN_bytes( G ) ) ) );
  A := BIGNUM( AIdentityPrivateValue );
  U := BIGNUM( TIdSha512Hash.Digest( TIdBytes.From( AIdentityPublicValue ).Append( AServerPublicValue ) ) );
  V := BIGNUM;
  T := BIGNUM;
  L := BIGNUM;
  P := BIGNUM;
  Q := BIGNUM;
  R := BIGNUM;
  C := BN_CTX_new;
  BN_mod_exp( V, G, X, N, C );
  BN_mul( T, V, K, C );
  BN_sub( L, B, T );
  BN_mul( P, U, X, C );
  BN_add( Q, A, P );
  BN_mod_exp( R, L, Q, N, C );
  Result := BN_bytes( R );
  BN_free( N );
  BN_free( G );
  BN_free( B );
  BN_free( X );
  BN_free( K );
  BN_free( A );
  BN_free( U );
  BN_free( V );
  BN_free( T );
  BN_free( L );
  BN_free( P );
  BN_free( Q );
  BN_free( R );
  BN_CTX_free( C );
end;


class function TSRP.VerifierMessage( const AUserName: String; const ASalt, AServerPublicValue, AIdentityPublicValue, AKey: TIdBytes ): TIdBytes;
var
  N: PBIGNUM;
  G: PBIGNUM;
  R: PBIGNUM;
  X: TIdBytes;
  C: PBN_CTX;
begin
  N := BIGNUM( TIdBase64.Decode( SRP_NG_4096_N ) );
  G := BIGNUM( [ 5 ] );
  C := BN_CTX_new;
  R := BIGNUM;
  BN_mul( R, G, N, C );
  X := BN_bytes( R );
  Result.Assign( TIdSha512Hash.Digest( TIdBytes.From( X ).Append( AUserName ).Append( ASalt ).Append( AServerPublicValue ).Append( AIdentityPublicValue ).Append( AKey ) ) );
  Result.Assign( TIdSha512Hash.Digest( TIdBytes.From( AIdentityPublicValue ).Append( Result ).Append( AKey ) ) );
  BN_free( N );
  BN_free( G );
  BN_free( R );
  BN_CTX_free( C );
  X.Clear;
end;

スクリーンショット

ここに画像の説明を入力

4

0 に答える 0