PageRenderTime 405ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/test/jquery-webcryptoapi-tests.js

https://github.com/hakanson/todomvc-jquery-webcryptoapi
JavaScript | 265 lines | 161 code | 63 blank | 41 comment | 2 complexity | cd7b3aad631aa54f1835f3d8606ceae8 MD5 | raw file
  1. (function () {
  2. 'use strict';
  3. // comment out next line to force use of browser native window.crypto object
  4. var crypto = $.WebCryptoAPI;
  5. var testVector = {
  6. data: 'The quick brown fox jumps over the lazy dog',
  7. sha1Hash : '2fd4e1c67a2d28fced849ee1bb76e7391b93eb12',
  8. sha256Hash : 'd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592',
  9. key: 'key',
  10. sha1HMAC : 'de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9',
  11. sha256HMAC : 'f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8'
  12. };
  13. var hmacSha1 = { name: 'hmac', hash: { name: 'sha-1' } };
  14. var hmacSha256 = { name: 'hmac', hash: { name: 'sha-256' } };
  15. var encoder = new TextEncoder();
  16. var decoder = new TextDecoder();
  17. var dataBuf = encoder.encode( testVector.data );
  18. var keyBuf = encoder.encode( testVector.key );
  19. QUnit.extend( QUnit.assert, {
  20. promise: function ( promise ) {
  21. var assert = this;
  22. QUnit.stop();
  23. promise.catch( function ( err ) {
  24. assert.ok( false, err.message );
  25. }).then( function ( ) {
  26. QUnit.start();
  27. });
  28. }
  29. });
  30. QUnit.module( 'Web Cryptography API' );
  31. QUnit.test( 'SubtleCrypto interface' , function ( assert ) {
  32. assert.ok(window.crypto, 'window.crypto');
  33. assert.ok(window.crypto && window.crypto.subtle, 'window.crypto.subtle');
  34. assert.ok(window.msCrypto, 'window.msCrypto');
  35. assert.ok(window.msrCrypto, 'window.msrCrypto');
  36. assert.ok(window.crypto && window.crypto.webkitSubtle, 'window.crypto.webkitSubtle');
  37. });
  38. /*
  39. QUnit.test( 'SHA-1', function ( assert ) {
  40. // OpenSSL command line
  41. // echo -n "The quick brown fox jumps over the lazy dog" | openssl dgst -sha1
  42. // (stdin)= 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12
  43. QUnit.stop();
  44. crypto.subtle.digest( { name: 'sha-1' }, dataBuf ).then( function ( result ) {
  45. var hash = $.Uint8Util.toHexString( new Uint8Array( result ) );
  46. assert.equal( hash, testVector.sha1Hash );
  47. }).catch( function ( e ) {
  48. assert.ok( false, e.message );
  49. }).then( function ( ) {
  50. QUnit.start();
  51. });
  52. });
  53. */
  54. QUnit.test( 'SHA-1', function ( assert ) {
  55. // OpenSSL command line
  56. // echo -n "The quick brown fox jumps over the lazy dog" | openssl dgst -sha1
  57. // (stdin)= 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12
  58. assert.promise( crypto.subtle.digest( { name: 'sha-1' }, dataBuf ).then( function ( result ) {
  59. var hash = $.Uint8Util.toHexString( new Uint8Array( result ) );
  60. assert.equal( hash, testVector.sha1Hash );
  61. }));
  62. });
  63. QUnit.test( 'HMAC using SHA-1', function ( assert ) {
  64. // OpenSSL command line
  65. // echo -n "The quick brown fox jumps over the lazy dog" | openssl dgst -sha1 -hmac "key"
  66. // (stdin)= de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9
  67. assert.promise( crypto.subtle.importKey( 'raw', keyBuf, hmacSha1, true, ['sign', 'verify'] ).then( function ( keyResult ) {
  68. return crypto.subtle.sign( hmacSha1, keyResult, dataBuf ).then( function ( signResult ) {
  69. var hash = $.Uint8Util.toHexString( new Uint8Array( signResult ) );
  70. assert.equal( hash, testVector.sha1HMAC );
  71. })
  72. }));
  73. });
  74. QUnit.test( 'SHA-256', function ( assert ) {
  75. // OpenSSL command line
  76. // $ echo -n "The quick brown fox jumps over the lazy dog" | openssl dgst -sha256
  77. // (stdin)= d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592
  78. assert.promise( crypto.subtle.digest( { name: 'sha-256' }, dataBuf ).then( function ( result ) {
  79. var hash = $.Uint8Util.toHexString( new Uint8Array( result ) );
  80. assert.equal( hash, testVector.sha256Hash );
  81. }));
  82. });
  83. QUnit.test( 'HMAC using SHA-256', function ( assert ) {
  84. // Wikipedia article
  85. // HMAC_SHA256("key", "The quick brown fox jumps over the lazy dog") = 0xf7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8
  86. // OpenSSL command line
  87. // echo -n "The quick brown fox jumps over the lazy dog" | openssl dgst -sha256 -hmac "key"
  88. // (stdin)= f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8
  89. // $ echo -n "The quick brown fox jumps over the lazy dog" | openssl dgst -sha256 -mac HMAC -macopt hexkey:6b6579
  90. // (stdin)= f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8
  91. assert.promise( crypto.subtle.importKey( 'raw', keyBuf, hmacSha256, true, ['sign', 'verify'] ).then( function ( keyResult ) {
  92. return crypto.subtle.sign( hmacSha256, keyResult, dataBuf ).then( function ( signResult ) {
  93. var hash = $.Uint8Util.toHexString( new Uint8Array( signResult ) );
  94. assert.equal( hash, testVector.sha256HMAC );
  95. });
  96. }));
  97. });
  98. QUnit.test( 'AES-CBC (nested Promises)', function ( assert ) {
  99. // $ echo -n "Message" | openssl enc -aes256 -K 0CD1D07EB67E19EF56EA0F3A9A8F8A7C957A2CB208327E0E536608FF83256C96 -iv 6C4C31BDAB7BAFD35B23691EC521E28D | xxd -p
  100. // 23e5ebe72d99cf302c99183c05cf050a
  101. var testVector = {
  102. plaintext: 'Message',
  103. iv: '6C4C31BDAB7BAFD35B23691EC521E28D',
  104. key: '0CD1D07EB67E19EF56EA0F3A9A8F8A7C957A2CB208327E0E536608FF83256C96',
  105. ciphertext: '23e5ebe72d99cf302c99183c05cf050a'
  106. };
  107. var buf = encoder.encode( testVector.plaintext );
  108. var keyBuf = $.Uint8Util.fromHexString( testVector.key );
  109. var ivBuf = $.Uint8Util.fromHexString( testVector.iv );
  110. assert.promise( crypto.subtle.importKey( 'raw', keyBuf, { name: 'AES-CBC' }, true, ['encrypt', 'decrypt'] ).then( function ( encryptionKey ) {
  111. var aesCbc = { name: 'AES-CBC', iv: ivBuf };
  112. return crypto.subtle.encrypt( aesCbc, encryptionKey, buf ).then( function ( encryptResult ) {
  113. var encryptBuf = new Uint8Array( encryptResult );
  114. var ciphertext = $.Uint8Util.toHexString( encryptBuf );
  115. assert.equal( ciphertext, testVector.ciphertext );
  116. return crypto.subtle.decrypt( aesCbc, encryptionKey, encryptBuf ).then( function ( decryptResult ) {
  117. var plaintext = decoder.decode( new Uint8Array( decryptResult ) );
  118. assert.equal( plaintext, testVector.plaintext );
  119. });
  120. });
  121. }));
  122. });
  123. QUnit.test( 'AES-CBC (chained Promises)', function ( assert ) {
  124. // $ echo -n "Message" | openssl enc -aes256 -K 0CD1D07EB67E19EF56EA0F3A9A8F8A7C957A2CB208327E0E536608FF83256C96 -iv 6C4C31BDAB7BAFD35B23691EC521E28D | xxd -p
  125. // 23e5ebe72d99cf302c99183c05cf050a
  126. var testVector = {
  127. plaintext: 'Message',
  128. iv: '6C4C31BDAB7BAFD35B23691EC521E28D',
  129. key: '0CD1D07EB67E19EF56EA0F3A9A8F8A7C957A2CB208327E0E536608FF83256C96',
  130. ciphertext: '23e5ebe72d99cf302c99183c05cf050a'
  131. };
  132. var buf = encoder.encode( testVector.plaintext );
  133. var keyBuf = $.Uint8Util.fromHexString( testVector.key );
  134. var ivBuf = $.Uint8Util.fromHexString( testVector.iv );
  135. var aesCbc = { name: 'AES-CBC', iv: ivBuf };
  136. var encryptionKey;
  137. function importKey () {
  138. return crypto.subtle.importKey( 'raw', keyBuf, { name: 'AES-CBC' }, true, ['encrypt', 'decrypt'] )
  139. }
  140. function encrypt ( importedKey ) {
  141. encryptionKey = importedKey;
  142. return crypto.subtle.encrypt( aesCbc, encryptionKey, buf );
  143. }
  144. function decrypt ( encryptResult ) {
  145. var encryptBuf = new Uint8Array( encryptResult );
  146. var ciphertext = $.Uint8Util.toHexString( encryptBuf );
  147. assert.equal( ciphertext, testVector.ciphertext );
  148. return crypto.subtle.decrypt( aesCbc, encryptionKey, encryptBuf );
  149. }
  150. function compare ( decryptResult ) {
  151. var plaintext = decoder.decode( new Uint8Array( decryptResult ) );
  152. assert.equal( plaintext, testVector.plaintext );
  153. }
  154. assert.promise( importKey()
  155. .then( encrypt )
  156. .then( decrypt )
  157. .then( compare )
  158. );
  159. });
  160. QUnit.test( 'PBKDF2', function ( assert ) {
  161. var testVector = {
  162. password : 'password',
  163. salt: 'cf7488cd1e48e84990f51b3f121e161318ba2098aa6c993ded1012c955d5a3e8',
  164. iterations: 100,
  165. key: 'c12b2e03a08f3f0d23f3c4429c248c275a728814053a093835e803bc8e695b4e'
  166. };
  167. var alg = {
  168. name: 'PBKDF2',
  169. hash: 'SHA-1',
  170. salt: $.Uint8Util.fromHexString( testVector.salt ),
  171. iterations: testVector.iterations
  172. };
  173. var passwordBuf = encoder.encode( testVector.password );
  174. assert.promise( crypto.subtle.importKey('raw', passwordBuf, 'PBKDF2', false, ['deriveKey']).then(function ( keyResult ) {
  175. return crypto.subtle.deriveBits( alg, keyResult, 256 ).then(function ( deriveResult ) {
  176. var deriveBuf = new Uint8Array( deriveResult );
  177. var key = $.Uint8Util.toHexString( deriveBuf );
  178. assert.equal( key, testVector.key );
  179. });
  180. }));
  181. });
  182. QUnit.module( 'Invalid Algorithm' );
  183. QUnit.test( 'KJH-256', function ( assert ) {
  184. assert.promise( crypto.subtle.digest( { name: 'kjh-256' }, dataBuf ).then( function ( result ) {
  185. var hash = $.Uint8Util.toHexString( new Uint8Array( result ) );
  186. assert.equal( hash, 'kjh' );
  187. }));
  188. });
  189. QUnit.test( 'HMAC using KJH-256', function ( assert ) {
  190. var hmacKjh256 = { name: 'hmac', hash: { name: 'kjh-256' } };
  191. assert.promise( crypto.subtle.importKey( 'raw', keyBuf, hmacKjh256, true, ['sign', 'verify'] ).then( function ( keyResult ) {
  192. return crypto.subtle.sign( hmacKjh256, keyResult, dataBuf ).then( function ( signResult ) {
  193. var hash = $.Uint8Util.toHexString( new Uint8Array( signResult ) );
  194. assert.equal( hash, 'kjh' );
  195. })
  196. }));
  197. });
  198. })();