Comparing version 0.3.1 to 0.4.0
var CryptoJS = require('crypto-js/core'); | ||
var AES = require('crypto-js/aes'); | ||
var Utf8 = require('crypto-js/enc-utf8'); | ||
var AES = require('crypto-js/aes'); | ||
var Utf8 = require('crypto-js/enc-utf8'); | ||
var Latin1 = require('crypto-js/enc-latin1'); | ||
@@ -12,3 +12,3 @@ var Hex = require('crypto-js/enc-hex'); | ||
//lpad a string for some hex conversions | ||
String.prototype.lpad = function(padString, length) { | ||
String.prototype.lpad = function (padString, length) { | ||
var str = this; | ||
@@ -20,3 +20,3 @@ while (str.length < length) str = padString + str; | ||
//Makes a Base64 string a url-safe base64 string | ||
var urlsafe = function urlsafe(string){ | ||
var urlsafe = function urlsafe(string) { | ||
return string.replace(/\+/g, '-').replace(/\//g, '_') //.replace(/=+$/, '') | ||
@@ -26,3 +26,3 @@ } | ||
// parse a Hex string to an Int | ||
var parseHex = function parseHex(hexString){ | ||
var parseHex = function parseHex(hexString) { | ||
return parseInt('0x' + hexString); | ||
@@ -32,3 +32,3 @@ } | ||
// turn bits into number of chars in a hex string | ||
var hexBits = function hexBits(bits){ | ||
var hexBits = function hexBits(bits) { | ||
return bits / 8 * 2; | ||
@@ -38,3 +38,3 @@ } | ||
// convert base64 string to hex string | ||
var decode64toHex = function decode64(string){ | ||
var decode64toHex = function decode64(string) { | ||
var s = URLBase64.decode(string.replace(/=+$/, '')); | ||
@@ -45,6 +45,6 @@ return (new Buffer(s)).toString('hex'); | ||
// convert array to hex string | ||
var ArrayToHex = function ArrayToHex(array){ | ||
var ArrayToHex = function ArrayToHex(array) { | ||
var hex = ''; | ||
for( var _byte in array){ | ||
hex += Number(_byte).toString(16).lpad('0',2); | ||
for (var _byte in array) { | ||
hex += Number(_byte).toString(16).lpad('0', 2); | ||
} | ||
@@ -54,11 +54,11 @@ return hex; | ||
var randomHex = function(size){ | ||
return crypto.randomBytes(128/8).toString('hex') | ||
var randomHex = function (size) { | ||
return crypto.randomBytes(128 / 8).toString('hex') | ||
} | ||
var setIV = function setIV(iv_array){ | ||
if(iv_array){ | ||
var setIV = function setIV(iv_array) { | ||
if (iv_array) { | ||
this.ivHex = ArrayToHex(iv_array); | ||
}else{ | ||
this.ivHex = randomHex(128/8); | ||
} else { | ||
this.ivHex = randomHex(128 / 8); | ||
} | ||
@@ -70,6 +70,6 @@ this.iv = Hex.parse(this.ivHex); | ||
//convert Time object or now into WordArray | ||
var timeBytes = function timeBytes(time){ | ||
if(time){ | ||
var timeBytes = function timeBytes(time) { | ||
if (time) { | ||
time = (time / 1000) | ||
}else{ | ||
} else { | ||
time = (Math.round(new Date() / 1000)) | ||
@@ -82,3 +82,3 @@ } | ||
var fernet = function fernet(opts){ | ||
var fernet = function fernet(opts) { | ||
this.Hex = Hex; | ||
@@ -92,3 +92,3 @@ this.Base64 = Base64; | ||
//Sets the secret from base64 encoded value | ||
this.setSecret = function setSecret(secret64){ | ||
this.setSecret = function setSecret(secret64) { | ||
this.secret = new this.Secret(secret64); | ||
@@ -101,14 +101,14 @@ return this.secret; | ||
this.encryptMessage = function(message, encryptionKey, iv){ | ||
var encrypted = AES.encrypt(message, encryptionKey, {iv: iv}); | ||
this.encryptMessage = function (message, encryptionKey, iv) { | ||
var encrypted = AES.encrypt(message, encryptionKey, { iv: iv }); | ||
return encrypted.ciphertext; | ||
} | ||
this.decryptMessage = function(cipherText, encryptionKey, iv){ | ||
this.decryptMessage = function (cipherText, encryptionKey, iv) { | ||
var encrypted = {}; | ||
encrypted.key=encryptionKey; | ||
encrypted.iv=iv; | ||
encrypted.key = encryptionKey; | ||
encrypted.iv = iv; | ||
encrypted.ciphertext = cipherText; | ||
var decrypted = AES.decrypt(encrypted, encryptionKey, {iv: iv}); | ||
var decrypted = AES.decrypt(encrypted, encryptionKey, { iv: iv }); | ||
@@ -120,3 +120,3 @@ return decrypted.toString(Utf8); | ||
this.createToken = function(signingKey, time, iv, cipherText){ | ||
this.createToken = function (signingKey, time, iv, cipherText) { | ||
var hmac = this.createHmac(signingKey, time, iv, cipherText); | ||
@@ -140,3 +140,3 @@ var tokenWords = Hex.parse(this.versionHex); | ||
this.Secret = require('./lib/secret'); | ||
this.Token = require('./lib/token')(this); | ||
this.Token = require('./lib/token')(this); | ||
@@ -146,6 +146,6 @@ opts = opts || {}; | ||
// because (0 || x) always equals x | ||
if(opts.ttl === 0) this.ttl = 0; | ||
if (opts.ttl === 0) this.ttl = 0; | ||
this.versionHex = '80'; | ||
this.setIV(opts.iv); | ||
if(opts.secret){ this.setSecret(opts.secret) } | ||
if (opts.secret) { this.setSecret(opts.secret) } | ||
} | ||
@@ -152,0 +152,0 @@ |
var f = require('../fernet'); | ||
var Secret = function(secret64){ | ||
var Secret = function (secret64) { | ||
var secret = f.decode64toHex(secret64); | ||
if (secret.length !== f.hexBits(256)) { | ||
throw new Error('Secret must be 32 url-safe base64-encoded bytes.'); | ||
throw new Error('Secret must be 32 url-safe base64-encoded bytes.'); | ||
} | ||
this.signingKeyHex = secret.slice(0,f.hexBits(128)); | ||
this.signingKey = f.Hex.parse(this.signingKeyHex); | ||
this.signingKeyHex = secret.slice(0, f.hexBits(128)); | ||
this.signingKey = f.Hex.parse(this.signingKeyHex); | ||
this.encryptionKeyHex = secret.slice(f.hexBits(128)); | ||
this.encryptionKey = f.Hex.parse(this.encryptionKeyHex); | ||
this.encryptionKey = f.Hex.parse(this.encryptionKeyHex); | ||
} | ||
exports = module.exports = Secret; |
var fernet = require('../fernet'); | ||
//TokenFoctory | ||
module = module.exports = function(parent){ | ||
var Token = function Token(opts){ | ||
module = module.exports = function (parent) { | ||
var Token = function Token(opts) { | ||
opts = opts || {}; | ||
this.secret = opts.secret || parent.secret; | ||
this.ttl = opts.ttl || parent.ttl; | ||
if(opts.ttl === 0) this.ttl = 0; | ||
this.message = opts.message; | ||
this.secret = opts.secret || parent.secret; | ||
this.ttl = opts.ttl || parent.ttl; | ||
if (opts.ttl === 0) this.ttl = 0; | ||
this.message = opts.message; | ||
this.cipherText = opts.cipherText; | ||
this.token = opts.token; | ||
this.version = opts.version || fernet.parseHex(parent.versionHex); | ||
this.optsIV = opts.iv; | ||
this.maxClockSkew = 60; | ||
if(opts.time) this.setTime(Date.parse(opts.time)); | ||
this.token = opts.token; | ||
this.version = opts.version || fernet.parseHex(parent.versionHex); | ||
this.optsIV = opts.iv; | ||
this.maxClockSkew = 60; | ||
if (opts.time) this.setTime(Date.parse(opts.time)); | ||
else this.setTime(); | ||
@@ -22,14 +22,14 @@ } | ||
setIV: fernet.setIV, | ||
setTime: function tokenSetTime(time){ | ||
setTime: function tokenSetTime(time) { | ||
this.time = fernet.timeBytes(time); | ||
}, | ||
toString: function tokenToString(){ | ||
if(this.encoded){ | ||
toString: function tokenToString() { | ||
if (this.encoded) { | ||
return this.token | ||
}else{ | ||
} else { | ||
return this.message | ||
} | ||
}, | ||
encode: function encodeToken(message){ | ||
if(!this.secret) throw(new Error("Secret not set")); | ||
encode: function encodeToken(message) { | ||
if (!this.secret) throw (new Error("Secret not set")); | ||
this.encoded = true; | ||
@@ -39,24 +39,24 @@ this.setIV(this.optsIV); //if null will always be a fresh IV | ||
this.cipherText = fernet.encryptMessage(this.message, this.secret.encryptionKey, this.iv); | ||
this.token = fernet.createToken(this.secret.signingKey,this.time, this.iv, this.cipherText) | ||
this.token = fernet.createToken(this.secret.signingKey, this.time, this.iv, this.cipherText) | ||
return this.token; | ||
}, | ||
decode: function decodeToken(token){ | ||
if(!this.secret) throw(new Error("Secret not set")); | ||
decode: function decodeToken(token) { | ||
if (!this.secret) throw (new Error("Secret not set")); | ||
this.encoded = false; | ||
this.token = token || this.token; | ||
var tokenString = fernet.decode64toHex(this.token); | ||
var tokenString = fernet.decode64toHex(this.token); | ||
var versionOffset = fernet.hexBits(8); | ||
var timeOffset = versionOffset + fernet.hexBits(64); | ||
var ivOffset = timeOffset + fernet.hexBits(128); | ||
var hmacOffset = tokenString.length - fernet.hexBits(256); | ||
var timeInt = fernet.parseHex(tokenString.slice(versionOffset, timeOffset)); | ||
var timeOffset = versionOffset + fernet.hexBits(64); | ||
var ivOffset = timeOffset + fernet.hexBits(128); | ||
var hmacOffset = tokenString.length - fernet.hexBits(256); | ||
var timeInt = fernet.parseHex(tokenString.slice(versionOffset, timeOffset)); | ||
this.version = fernet.parseHex(tokenString.slice(0,versionOffset)); | ||
this.version = fernet.parseHex(tokenString.slice(0, versionOffset)); | ||
if(this.version != 128){ | ||
if (this.version != 128) { | ||
throw new Error("Invalid version"); | ||
} | ||
this.time = new Date(timeInt * 1000); | ||
this.time = new Date(timeInt * 1000); | ||
@@ -66,15 +66,17 @@ var currentTime = new Date() | ||
if(this.ttl > 0 && timeDiff > this.ttl) { | ||
throw new Error("Invalid Token: TTL"); | ||
} | ||
if (this.ttl > 0) { | ||
if (timeDiff > this.ttl) { | ||
throw new Error("Invalid Token: TTL"); | ||
} | ||
if(((currentTime / 1000) + this.maxClockSkew) < timeInt){ | ||
throw new Error("far-future timestamp"); | ||
if (((currentTime / 1000) + this.maxClockSkew) < timeInt) { | ||
throw new Error("far-future timestamp"); | ||
} | ||
} | ||
this.ivHex = tokenString.slice(timeOffset, ivOffset); | ||
this.iv = fernet.Hex.parse(this.ivHex); | ||
this.ivHex = tokenString.slice(timeOffset, ivOffset); | ||
this.iv = fernet.Hex.parse(this.ivHex); | ||
this.cipherTextHex = tokenString.slice(ivOffset, hmacOffset); | ||
this.cipherText = fernet.Hex.parse(this.cipherTextHex); | ||
this.hmacHex = tokenString.slice(hmacOffset); | ||
this.hmacHex = tokenString.slice(hmacOffset); | ||
var decodedHmac = fernet.createHmac(this.secret.signingKey, fernet.timeBytes(this.time), this.iv, this.cipherText); | ||
@@ -84,8 +86,8 @@ var decodedHmacHex = decodedHmac.toString(fernet.Hex); | ||
var accum = 0 | ||
for(var i=0;i<64;i++){ | ||
for (var i = 0; i < 64; i++) { | ||
accum += decodedHmacHex.charCodeAt(i) ^ this.hmacHex.charCodeAt(i) | ||
} | ||
if(accum != 0) throw new Error("Invalid Token: HMAC"); | ||
if (accum != 0) throw new Error("Invalid Token: HMAC"); | ||
this.message = fernet.decryptMessage(this.cipherText, this.secret.encryptionKey, this.iv) | ||
this.message = fernet.decryptMessage(this.cipherText, this.secret.encryptionKey, this.iv) | ||
return this.message; | ||
@@ -92,0 +94,0 @@ } |
{ | ||
"name": "fernet", | ||
"version": "0.3.1", | ||
"version": "0.4.0", | ||
"description": "Javascript implementation of Fernet symmetric encryption https://github.com/kr/fernet-spec", | ||
@@ -8,3 +8,3 @@ "main": "fernet.js", | ||
"pretest": "browserify -s fernet fernet.js > fernetBrowser.js", | ||
"test": "mocha", | ||
"test": "mocha test/*.js", | ||
"posttest": "open test.html" | ||
@@ -26,4 +26,4 @@ }, | ||
"buffer-browserify": "~0.2.2", | ||
"mocha": "*", | ||
"chai": "*", | ||
"mocha": "^9.1.2", | ||
"sinon": "*", | ||
@@ -30,0 +30,0 @@ "sinon-chai": "*" |
//for browser compatibility | ||
if(!chai) var chai = require('chai'); | ||
if(!sinon) var sinon = require("sinon"); | ||
if(!sinonChai) var sinonChai = require("sinon-chai"); | ||
if(!fernet) var fernet = require('../fernet'); | ||
if (!chai) var chai = require('chai'); | ||
if (!sinon) var sinon = require("sinon"); | ||
if (!sinonChai) var sinonChai = require("sinon-chai"); | ||
if (!fernet) var fernet = require('../fernet'); | ||
@@ -25,7 +25,7 @@ var assert = chai.assert | ||
suite('fernet.Token.prototype.decode', function(){ | ||
var _fernet = new fernet({ttl: 0}) | ||
var secret = new fernet.Secret(testData.secret); | ||
suite('fernet.Token.prototype.decode', function () { | ||
var _fernet = new fernet({ ttl: 0 }) | ||
var secret = new fernet.Secret(testData.secret); | ||
test("decode()", function(){ | ||
test("decode()", function () { | ||
var token = new _fernet.Token({ | ||
@@ -40,4 +40,4 @@ secret: secret, | ||
test("decode(token)", function(){ | ||
var token = new _fernet.Token({secret: secret}) | ||
test("decode(token)", function () { | ||
var token = new _fernet.Token({ secret: secret }) | ||
assert.equal("hello", token.decode(testData.token)) | ||
@@ -47,4 +47,4 @@ assert.equal("hello", token.toString()) | ||
test("decode(token) with top-level secret", function(){ | ||
var f = new fernet({secret: testData.secret, ttl: 0}) | ||
test("decode(token) with top-level secret", function () { | ||
var f = new fernet({ secret: testData.secret, ttl: 0 }) | ||
var token = new f.Token() | ||
@@ -55,3 +55,3 @@ assert.equal("hello", token.decode(testData.token)) | ||
test('recovers version', function(){ | ||
test('recovers version', function () { | ||
var token = new _fernet.Token({ | ||
@@ -67,3 +67,3 @@ secret: secret, | ||
test('recovers time', function(){ | ||
test('recovers time', function () { | ||
var token = new _fernet.Token({ | ||
@@ -78,3 +78,3 @@ secret: secret, | ||
test('recovers iv', function(){ | ||
test('recovers iv', function () { | ||
var token = new _fernet.Token({ | ||
@@ -89,3 +89,3 @@ secret: secret, | ||
test('recovers hmac', function(){ | ||
test('recovers hmac', function () { | ||
var token = new _fernet.Token({ | ||
@@ -100,4 +100,4 @@ secret: secret, | ||
test('inherits parent TTL', function(){ | ||
var f = new fernet({ttl: 1}); | ||
test('inherits parent TTL', function () { | ||
var f = new fernet({ ttl: 1 }); | ||
var token = new f.Token({ | ||
@@ -108,3 +108,3 @@ secret: secret, | ||
assert.throws(function(){ | ||
assert.throws(function () { | ||
token.decode(); | ||
@@ -114,3 +114,3 @@ }, Error, 'Invalid Token: TTL'); | ||
test('raises new Error("Invalid Token: TTL") on invalid ttl', function(){ | ||
test('raises new Error("Invalid Token: TTL") on invalid ttl', function () { | ||
var token = new fernet.Token({ | ||
@@ -122,3 +122,3 @@ secret: secret, | ||
assert.throws(function(){ | ||
assert.throws(function () { | ||
token.decode(); | ||
@@ -128,3 +128,3 @@ }, Error, 'Invalid Token: TTL'); | ||
test('raises new Error("Invalid version") on wrong version byte', function(){ | ||
test('raises new Error("Invalid version") on wrong version byte', function () { | ||
var tokenHex = fernet.decode64toHex(testData.token); | ||
@@ -135,5 +135,5 @@ var versionOffset = fernet.hexBits(8); | ||
var token = fernet.urlsafe(tokenWords.toString(fernet.Base64)); | ||
var t = new _fernet.Token({secret: secret}) | ||
var t = new _fernet.Token({ secret: secret }) | ||
assert.throws(function(){ | ||
assert.throws(function () { | ||
t.decode(token); | ||
@@ -143,7 +143,7 @@ }, Error, 'Invalid version'); | ||
test('raises new Error("Invalid Token: HMAC") on wrong Hmac', function(){ | ||
test('raises new Error("Invalid Token: HMAC") on wrong Hmac', function () { | ||
var s = testData.token; | ||
var i = s.length - 5; | ||
var mutation = String.fromCharCode(s.charCodeAt(i) + 1); | ||
var dirtyHmacString = s.slice(0,i) + mutation + s.slice(i+1); | ||
var dirtyHmacString = s.slice(0, i) + mutation + s.slice(i + 1); | ||
var token = new _fernet.Token({ | ||
@@ -154,3 +154,3 @@ secret: secret, | ||
assert.throws(function(){ | ||
assert.throws(function () { | ||
token.decode(); | ||
@@ -160,7 +160,7 @@ }, Error, 'Invalid Token: HMAC'); | ||
test('raises new Error("far-future timestamp") on unacceptable clock skew', function(){ | ||
test('raises new Error("far-future timestamp") on unacceptable clock skew', function () { | ||
var token = new fernet.Token({ | ||
secret: new fernet.Secret(unacceptableClockSkewTestData.secret), | ||
token: unacceptableClockSkewTestData.token, | ||
ttl: 0 | ||
ttl: 1 | ||
}) | ||
@@ -170,3 +170,3 @@ | ||
assert.throws(function(){ | ||
assert.throws(function () { | ||
token.decode(); | ||
@@ -173,0 +173,0 @@ }, Error, 'far-future timestamp'); |
//for browser compatibility | ||
if(!chai) var chai = require('chai'); | ||
if(!fernet) var fernet = require('../fernet'); | ||
if (!chai) var chai = require('chai'); | ||
if (!fernet) var fernet = require('../fernet'); | ||
@@ -15,4 +15,4 @@ var assert = chai.assert; | ||
suite('fernet.Token', function(){ | ||
test('contains a version', function(){ | ||
suite('fernet.Token', function () { | ||
test('contains a version', function () { | ||
var token = new fernet.Token() | ||
@@ -24,6 +24,6 @@ assert.equal(128, token.version) | ||
suite('fernet.Token.prototype.encode', function(){ | ||
suite('fernet.Token.prototype.encode', function () { | ||
var secret = new fernet.Secret(testData.secret); | ||
test("encode(message)", function(){ | ||
test("encode(message)", function () { | ||
var token = new fernet.Token({ | ||
@@ -38,3 +38,3 @@ secret: secret, | ||
test("token.encode() makes token.toString() return the token", function(){ | ||
test("token.encode() makes token.toString() return the token", function () { | ||
var token = new fernet.Token({ | ||
@@ -50,3 +50,3 @@ secret: secret, | ||
test("encode() returns the token as a String", function(){ | ||
test("encode() returns the token as a String", function () { | ||
var token = new fernet.Token({ | ||
@@ -60,3 +60,3 @@ secret: secret, | ||
test("randomly generates IV if one is not passed in", function(){ | ||
test("randomly generates IV if one is not passed in", function () { | ||
var token = new fernet.Token({ | ||
@@ -72,3 +72,3 @@ secret: secret, | ||
test('time defaults to Date.now()', function(){ | ||
test('time defaults to Date.now()', function () { | ||
var token = new fernet.Token({ | ||
@@ -75,0 +75,0 @@ secret: secret |
//for browser compatibility | ||
if(!chai) var chai = require('chai'); | ||
if(!fernet) var fernet = require('../fernet'); | ||
if (!chai) var chai = require('chai'); | ||
if (!fernet) var fernet = require('../fernet'); | ||
var assert = chai.assert; | ||
suite('fernet.Secret', function(){ | ||
suite('fernet.Secret', function () { | ||
@@ -14,21 +14,21 @@ var secret64 = "cw_0x689RpI-jtRR7oE8h_eQsKImvJapLeSbXpwF4e4="; | ||
test('secret.signingKeyHex', function(){ | ||
test('secret.signingKeyHex', function () { | ||
assert.equal(secret.signingKeyHex, signingKeyHex); | ||
}) | ||
test('secret.signingKey', function(){ | ||
test('secret.signingKey', function () { | ||
assert.deepEqual(secret.signingKey, fernet.Hex.parse(signingKeyHex)); | ||
}) | ||
test('secret.encryptionKeyHex', function(){ | ||
test('secret.encryptionKeyHex', function () { | ||
assert.equal(secret.encryptionKeyHex, encryptionKeyHex); | ||
}) | ||
test('secret.encryptionKey', function(){ | ||
test('secret.encryptionKey', function () { | ||
assert.deepEqual(secret.encryptionKey, fernet.Hex.parse(encryptionKeyHex)); | ||
}) | ||
test('raises "new Error(\'Secret must be 32 url-safe base64-encoded bytes.\')" on wrong secret', function(){ | ||
test('raises "new Error(\'Secret must be 32 url-safe base64-encoded bytes.\')" on wrong secret', function () { | ||
assert.throws(function(){ | ||
assert.throws(function () { | ||
new fernet.Secret('not a good secret'); | ||
@@ -35,0 +35,0 @@ }, Error, 'Secret must be 32 url-safe base64-encoded bytes.'); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
8665
308063
12