ClpDigestExample.pas 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. unit ClpDigestExample;
  2. interface
  3. uses
  4. SysUtils,
  5. ClpIDigest,
  6. ClpIMac,
  7. ClpDigestUtilities,
  8. ClpMacUtilities,
  9. ClpEncoders,
  10. ClpConverters,
  11. ClpKeyParameter,
  12. ClpPkcs5S2ParametersGenerator,
  13. ClpIPkcs5S2ParametersGenerator,
  14. ClpArgon2ParametersGenerator,
  15. ClpIArgon2ParametersGenerator,
  16. ClpScryptParametersGenerator,
  17. ClpIScryptParametersGenerator,
  18. ClpICipherParameters,
  19. ClpIKeyParameter,
  20. ClpCryptoLibTypes,
  21. ClpExampleBase;
  22. type
  23. TDigestExample = class(TExampleBase)
  24. public
  25. procedure Run; override;
  26. private
  27. procedure RunHash(const ADigestAlgorithm: string);
  28. procedure RunHmac(const AHmacAlgorithm: string);
  29. procedure RunPbkdf2(const ADigestAlgorithm: string);
  30. procedure RunArgon2D;
  31. procedure RunArgon2I;
  32. procedure RunArgon2Id;
  33. procedure RunScrypt;
  34. end;
  35. implementation
  36. procedure TDigestExample.RunHash(const ADigestAlgorithm: string);
  37. var
  38. LDigest: IDigest;
  39. LInput, LHash: TBytes;
  40. begin
  41. Logger.LogInformation('Digest: ' + ADigestAlgorithm);
  42. LInput := TConverters.ConvertStringToBytes('Hello CryptoLib', TEncoding.UTF8);
  43. LDigest := TDigestUtilities.GetDigest(ADigestAlgorithm);
  44. if LDigest = nil then
  45. begin
  46. Logger.LogWarning('Digest "' + ADigestAlgorithm + '" not available.');
  47. Exit;
  48. end;
  49. System.SetLength(LHash, LDigest.GetDigestSize);
  50. LDigest.BlockUpdate(LInput, 0, System.Length(LInput));
  51. LDigest.DoFinal(LHash, 0);
  52. Logger.LogInformation(Format('Hash %s: %s', [ADigestAlgorithm, THexEncoder.Encode(LHash, False)]));
  53. end;
  54. procedure TDigestExample.RunHmac(const AHmacAlgorithm: string);
  55. var
  56. LMac: IMac;
  57. LKey, LMsg, LResult: TBytes;
  58. begin
  59. Logger.LogInformation('HMAC: ' + AHmacAlgorithm);
  60. LKey := TConverters.ConvertStringToBytes('secret-key', TEncoding.UTF8);
  61. LMsg := TConverters.ConvertStringToBytes('message to authenticate', TEncoding.UTF8);
  62. LMac := TMacUtilities.GetMac(AHmacAlgorithm);
  63. if LMac = nil then
  64. begin
  65. Logger.LogWarning('HMAC "' + AHmacAlgorithm + '" not available.');
  66. Exit;
  67. end;
  68. LMac.Init(TKeyParameter.Create(LKey) as IKeyParameter);
  69. LMac.BlockUpdate(LMsg, 0, System.Length(LMsg));
  70. LResult := LMac.DoFinal;
  71. Logger.LogInformation(Format('%s: %s', [AHmacAlgorithm, THexEncoder.Encode(LResult, False)]));
  72. end;
  73. procedure TDigestExample.RunPbkdf2(const ADigestAlgorithm: string);
  74. var
  75. LGen: IPkcs5S2ParametersGenerator;
  76. LDigest: IDigest;
  77. LPassword, LSalt: TBytes;
  78. LParams: ICipherParameters;
  79. LKey: IKeyParameter;
  80. LDerived: TBytes;
  81. LIters: Int32;
  82. begin
  83. LIters := 10000;
  84. Logger.LogInformation(Format('PBKDF2: digest %s, %d iterations', [ADigestAlgorithm, LIters]));
  85. LPassword := TConverters.ConvertStringToBytes('password', TEncoding.UTF8);
  86. LSalt := TConverters.ConvertStringToBytes('salt', TEncoding.UTF8);
  87. LDigest := TDigestUtilities.GetDigest(ADigestAlgorithm);
  88. if LDigest = nil then
  89. begin
  90. Logger.LogWarning('Digest "' + ADigestAlgorithm + '" not available for PBKDF2.');
  91. Exit;
  92. end;
  93. LGen := TPkcs5S2ParametersGenerator.Create(LDigest) as IPkcs5S2ParametersGenerator;
  94. LGen.Init(LPassword, LSalt, LIters);
  95. LParams := LGen.GenerateDerivedParameters('AES', 256);
  96. if Supports(LParams, IKeyParameter, LKey) then
  97. begin
  98. LDerived := LKey.GetKey();
  99. Logger.LogInformation(Format('PBKDF2-HMAC-%s (%d iters) derived %d bytes: %s', [ADigestAlgorithm, LIters, System.Length(LDerived), THexEncoder.Encode(LDerived, False)]));
  100. end
  101. else
  102. Logger.LogWarning('PBKDF2: could not get key parameter.');
  103. end;
  104. procedure TDigestExample.RunArgon2D;
  105. var
  106. LGen: IArgon2ParametersGenerator;
  107. LPassword, LSalt: TBytes;
  108. LParams: ICipherParameters;
  109. LKey: IKeyParameter;
  110. LDerived: TBytes;
  111. begin
  112. LPassword := TConverters.ConvertStringToBytes('password', TEncoding.UTF8);
  113. LSalt := TConverters.ConvertStringToBytes('salt', TEncoding.UTF8);
  114. LGen := TArgon2ParametersGenerator.Create() as IArgon2ParametersGenerator;
  115. LGen.Init(TCryptoLibArgon2Type.Argon2D, TCryptoLibArgon2Version.Argon2Version13,
  116. LPassword, LSalt, nil, nil, 2, 65536, 1, TCryptoLibArgon2MemoryCostType.MemoryAsKB);
  117. LParams := LGen.GenerateDerivedParameters('AES', 256);
  118. if Supports(LParams, IKeyParameter, LKey) then
  119. begin
  120. LDerived := LKey.GetKey();
  121. Logger.LogInformation(Format('Argon2d (2 iters, 64 MiB, 1 lane) derived %d bytes: %s', [System.Length(LDerived), THexEncoder.Encode(LDerived, False)]));
  122. end
  123. else
  124. Logger.LogWarning('Argon2d: could not get key parameter.');
  125. end;
  126. procedure TDigestExample.RunArgon2I;
  127. var
  128. LGen: IArgon2ParametersGenerator;
  129. LPassword, LSalt: TBytes;
  130. LParams: ICipherParameters;
  131. LKey: IKeyParameter;
  132. LDerived: TBytes;
  133. begin
  134. LPassword := TConverters.ConvertStringToBytes('password', TEncoding.UTF8);
  135. LSalt := TConverters.ConvertStringToBytes('salt', TEncoding.UTF8);
  136. LGen := TArgon2ParametersGenerator.Create() as IArgon2ParametersGenerator;
  137. LGen.Init(TCryptoLibArgon2Type.Argon2I, TCryptoLibArgon2Version.Argon2Version13,
  138. LPassword, LSalt, nil, nil, 2, 65536, 1, TCryptoLibArgon2MemoryCostType.MemoryAsKB);
  139. LParams := LGen.GenerateDerivedParameters('AES', 256);
  140. if Supports(LParams, IKeyParameter, LKey) then
  141. begin
  142. LDerived := LKey.GetKey();
  143. Logger.LogInformation(Format('Argon2i (2 iters, 64 MiB, 1 lane) derived %d bytes: %s', [System.Length(LDerived), THexEncoder.Encode(LDerived, False)]));
  144. end
  145. else
  146. Logger.LogWarning('Argon2i: could not get key parameter.');
  147. end;
  148. procedure TDigestExample.RunArgon2Id;
  149. var
  150. LGen: IArgon2ParametersGenerator;
  151. LPassword, LSalt: TBytes;
  152. LParams: ICipherParameters;
  153. LKey: IKeyParameter;
  154. LDerived: TBytes;
  155. begin
  156. LPassword := TConverters.ConvertStringToBytes('password', TEncoding.UTF8);
  157. LSalt := TConverters.ConvertStringToBytes('salt', TEncoding.UTF8);
  158. LGen := TArgon2ParametersGenerator.Create() as IArgon2ParametersGenerator;
  159. LGen.Init(TCryptoLibArgon2Type.Argon2ID, TCryptoLibArgon2Version.Argon2Version13,
  160. LPassword, LSalt, nil, nil, 2, 65536, 1, TCryptoLibArgon2MemoryCostType.MemoryAsKB);
  161. LParams := LGen.GenerateDerivedParameters('AES', 256);
  162. if Supports(LParams, IKeyParameter, LKey) then
  163. begin
  164. LDerived := LKey.GetKey();
  165. Logger.LogInformation(Format('Argon2id (2 iters, 64 MiB, 1 lane) derived %d bytes: %s', [System.Length(LDerived), THexEncoder.Encode(LDerived, False)]));
  166. end
  167. else
  168. Logger.LogWarning('Argon2id: could not get key parameter.');
  169. end;
  170. procedure TDigestExample.RunScrypt;
  171. var
  172. LGen: IScryptParametersGenerator;
  173. LPassword, LSalt: TBytes;
  174. LParams: ICipherParameters;
  175. LKey: IKeyParameter;
  176. LDerived: TBytes;
  177. begin
  178. LPassword := TConverters.ConvertStringToBytes('password', TEncoding.UTF8);
  179. LSalt := TConverters.ConvertStringToBytes('salt', TEncoding.UTF8);
  180. LGen := TScryptParametersGenerator.Create() as IScryptParametersGenerator;
  181. LGen.Init(LPassword, LSalt, 16384, 8, 1);
  182. LParams := LGen.GenerateDerivedParameters('AES', 256);
  183. if Supports(LParams, IKeyParameter, LKey) then
  184. begin
  185. LDerived := LKey.GetKey();
  186. Logger.LogInformation(Format('Scrypt (N=16384, r=8, p=1) derived %d bytes: %s', [System.Length(LDerived), THexEncoder.Encode(LDerived, False)]));
  187. end
  188. else
  189. Logger.LogWarning('Scrypt: could not get key parameter.');
  190. end;
  191. procedure TDigestExample.Run;
  192. begin
  193. Logger.LogInformation('--- Digest example: Hash ---');
  194. RunHash('SHA-256');
  195. Logger.LogInformation('--- Digest example: HMAC ---');
  196. RunHmac('HMAC-SHA256');
  197. Logger.LogInformation('--- Digest example: Key derivation (PBKDF2) ---');
  198. RunPbkdf2('SHA-256');
  199. Logger.LogInformation('--- Digest example: Key derivation (Argon2d) ---');
  200. RunArgon2D;
  201. Logger.LogInformation('--- Digest example: Key derivation (Argon2i) ---');
  202. RunArgon2I;
  203. Logger.LogInformation('--- Digest example: Key derivation (Argon2id) ---');
  204. RunArgon2Id;
  205. Logger.LogInformation('--- Digest example: Key derivation (Scrypt) ---');
  206. RunScrypt;
  207. end;
  208. end.