3

终于在delphi中完成了SRP协议的实现!使用 openssl 库计算哈希和 Bignum。

最后的实现并不复杂。但我有疑问:

1)我可以使用随机对N,g。N 4096 位是否足够安全?

2) K,与 RFC 5054 一样,是一个强会话密钥,但长度为 768 字节,N 到 4906 位。那么如何才能正确地使用这个会话密钥和 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