alax / jsrp Goto Github PK
View Code? Open in Web Editor NEWJavaScript implementation of the Secure Remote Password protocol
License: MIT License
JavaScript implementation of the Secure Remote Password protocol
License: MIT License
It appears that the generator param for 8192 bits is incorrect here:
https://github.com/alax/jsrp/blob/master/src/parameters.coffee#L128
The spec calls for this value to be 19
https://tools.ietf.org/html/rfc5054#appendix-A
Thanks
Hello there i created a demo project to assist people needing help on implementing this library to their projects.
The repo is here .
Trying to browserify the release script and getting the following error:
Error: Can't walk dependency graph: Cannot find module './_stream_writable' from '/Users/wahal/go/src/github.com/envsecrets/jsrp/scripts/jsrp-browser.js'
required by /Users/wahal/go/src/github.com/envsecrets/jsrp/scripts/jsrp-browser.js
at /Users/wahal/.nvm/versions/node/v15.14.0/lib/node_modules/browserify/node_modules/resolve/lib/async.js:167:35
at load (/Users/wahal/.nvm/versions/node/v15.14.0/lib/node_modules/browserify/node_modules/resolve/lib/async.js:186:43)
at onex (/Users/wahal/.nvm/versions/node/v15.14.0/lib/node_modules/browserify/node_modules/resolve/lib/async.js:211:17)
at /Users/wahal/.nvm/versions/node/v15.14.0/lib/node_modules/browserify/node_modules/resolve/lib/async.js:24:69
at FSReqCallback.oncomplete (node:fs:193:21)
Command that I'm running:
browserify jsrp-browser.js -o bundle.js
SRP-6a is RFC 5054. This implementation uses the older SRP-3 K
calculation (RFC 2945). It also uses the alternative M
proof which I can't find on either RFC and is citation-needed on Wikipedia.
To comply with SRP-3 it should implement the correct M
calculation. I've included an implementation of M1 calculation to the spec. I haven't verified it as the Python library uses the newer K generation algorithm, so the output values do not line up, however, all the input values appear correct.
The only tricky thing is N_sbyte contains a leading zero, this is removed by starting the counter at 1, [1..(N_sbyte.length-1)]
. Might not even be necessary to convert the bytes to unsigned, as I did that before noticing the leading zero.
M1Spec: (options) ->
N = @params.N
g = @params.g
s = options.s # Buffer
I = options.I # Buffer
A = options.A # Buffer
B = options.B # Buffer
K = options.K # Buffer
N_sbyte = N.toByteArray()
N_ubyte = []
for i in [1..(N_sbyte.length-1)]
N_ubyte[i-1] = N_sbyte[i] & 0xFF
H_N = crypto
.createHash(@params.hash)
.update(N_ubyte)
.digest()
H_g = crypto
.createHash(@params.hash)
.update(g.toByteArray())
.digest()
H_I = crypto
.createHash(@params.hash)
.update(I)
.digest()
HN_xor_Hg = []
for i in [0..(H_I.length-1)]
HN_xor_Hg[i] = H_N[i] ^ H_g[i]
result = crypto
.createHash(@params.hash)
.update(HN_xor_Hg)
.update(H_I)
.update(s)
.update(A)
.update(B)
.update(K)
.digest()
return result
To comply with SRP-6a it should update the K
generation, as it is different now. See 2.6. Calculating the Premaster Secret (quoted below). The major change seems to be the introduction of lowercase k
, which acts a multiplier for g^x
.
The premaster secret is calculated by the client as follows:
I, P = <read from user>
N, g, s, B = <read from server>
a = random()
A = g^a % N
u = SHA1(PAD(A) | PAD(B))
k = SHA1(N | PAD(g))
x = SHA1(s | SHA1(I | ":" | P))
<premaster secret> = (B - (k * g^x)) ^ (a + (u * x)) % N
M = H(H(N) XOR H(g) | H(U) | s | A | B | K)
Detailed on page 4 of RFC 2945.
This library appears to use the alternate proof listed on Wikipedia (I didn't see it in the RFC).
I'll see about implementing it tomorrow, no promises though. Trying to interface with Python srp and the M values weren't matching up.
Update to new library )
Hello,
I've just published a pre-release version of a new Ruby Gem which implements SRP. I needed this code to be interoperable with Ruby clients and also at least one JavaScript client. I chose to use your jsrp
lib as the initial test case to implement against.
I would be grateful if you could take a look at it and maybe kick the tires a bit.
You can find it here:
https://github.com/grempe/sirp/blob/master/README.md
And the example server and client are in the examples
dir.
https://github.com/grempe/sirp/tree/master/examples
Once you start the server you should be able to just open the index.html
file to run the client with your jsrp code against the server.
Thanks again, and please feel free to share any issues you run into or suggestions.
https://github.com/grempe/sirp/issues
Glenn
I noticed that in Client.createVerifier() the saltBuf is always set to the salt value provided in the srp.generateSalt() callback. This consequently means that any salt set using setSalt() is not used when creating the verifier. This looks like a bug.
I have software that requires a custom set of N and g values as part of the parameters.
Providing an API for overriding these would allow me to use this library for my implementation.
For now I guess I can fork this and introduce my own method of importing them.
$ browserify jsrp.js --standalone jsrp > jsrp-browser.js
Error: Cannot find module 'jsbn' from '/path/to/jsrp/lib'
at /usr/lib/node_modules/browserify/node_modules/resolve/lib/async.js:46:17
at process (/usr/lib/node_modules/browserify/node_modules/resolve/lib/async.js:173:43)
at ondir (/usr/lib/node_modules/browserify/node_modules/resolve/lib/async.js:188:17)
at load (/usr/lib/node_modules/browserify/node_modules/resolve/lib/async.js:69:43)
at onex (/usr/lib/node_modules/browserify/node_modules/resolve/lib/async.js:92:31)
at /usr/lib/node_modules/browserify/node_modules/resolve/lib/async.js:22:47
at FSReqWrap.oncomplete (fs.js:117:15)
$ npm install jsbn
$ browserify jsrp.js --standalone jsrp > jsrp-browser.js
In the buffer module, the hexWrite throws "Invalid hex string" if the length of the hex string is not an even number. In java, for example BigInteger(15).toString(16) will gives "f", its length is odd(1), so hex string should be checked before being passed into jsrp, and in turn to buffer.
==============================
function hexWrite (buf, string, offset, length) {
offset = Number(offset) || 0
var remaining = buf.length - offset
if (!length) {
length = remaining
} else {
length = Number(length)
if (length > remaining) {
length = remaining
}
}
// must be an even number of digits
var strLen = string.length
if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')
Hi there, I've found a discrepancy with how the server library I'm using calculates M1.
Wikipedia defines M1 as:
Alternatively, in a password-only proof the calculation of K can be skipped and the shared S proven with:
M1 = H(A | B | SCarol)
which seems to be what my library is using.
However, this library seems to be using M1 = H(A | B | K), where K = H(S)
I would like to know where this discrepancy comes from, is it because of different versions of SRP? Thanks!
Related to #15
Running jsrp
in the browser in a Nuxt2 project. Using release package v0.2.4
.
Getting the following error in console of my browser:
TypeError: this.ABuf is undefined
Running the following code:
cPubKey = client.getPublicKey();
Getting the error from the following line:
getPublicKey() {
return this.ABuf.toString('hex'); // This line
}
Any solutions to this, @alax?
when 4096 bits is used, the client and the server can authenticate each other,
then I just change the length from 4096 (the default) to 1024, both claimed the other party is fake (not authentic).
If I describe it correctly, the client side needs to communicate with server side for at least 3 times
My issue here is that on server side each time when I get a request from client app, I need to init the jsrp server instance, then seems the instance is always different from previous one. So when I s.checkClientProof(M1)
, the result is always not true.
How do you persist the server instance? Sorry I am pretty new on this. Thanks in advance for your guidance.
TypeError: Cannot read property 'toString' of undefined
at TransBuffer.toHex (http://127.0.0.1:3000/build/init.js:1074:25)
at TransBuffer.toBigInteger (http://127.0.0.1:3000/build/init.js:1079:30)
at http://127.0.0.1:3000/build/init.js:915:35 at Object.exports.randomBytes (http://127.0.0.1:3000/build/init.js:3805:21)
at SRP.a (http://127.0.0.1:3000/build/init.js:913:21)
at Client.init (http://127.0.0.1:3000/build/init.js:463:23)
...
Can't use your build. Is it broken?
The code in question effectively is this:
let srpclient = new jsrp.client();
srpclient.init({
username: 'testUser',
password: 'password123'
}, () => {
srpclient.createVerifier((err, result) => {
console.log(result.salt, result.verifier);
this.io.emit('login', seed);
});
});
It might be worth noting that a build through browserify works as expected.
We have been doing a bunch of work creating security libraries in Javascript, for example :
Anyway I have been interested in playing with SRP and stumbled across your project, I have a questions:
What other SRP implementations has this been tested with?
Do you imagine it would be easy to retool to be based on WebCrypto?
Is there a sample client/server somewhere I could start with?
Thanks for your time.
Hi there!
We're building a platform using this package on the backend. We're working on an accompanying CLI written in Go and wanted something that's compatible but haven't been able to find any compatible implementations in Go โ Is there any that you could recommend?
Also, does this package only conform to the specification in RFC 2945 or also RFC 5054?
Thanks!
The M1 calculation is much different from what described here: http://srp.stanford.edu/design.html
And M2 calculation, I have seen other implementations use H(A|M1|S) rather than H(A|M1|K).
I guess it will be better to describe the formula in the readme page, so people can have an idea on the exact formula.
There has been a cleanup and new release in the jsbn project which you should follow.
You currently depend on v0.1.0
which should be updated in package.json
to be 1.1.0
. This will allow you to pick up future bugfixes while the 0.1.0 branch is now likely a dead-end.
See: andyperlitch/jsbn#14 for more info.
I found that when i set length 1024, the authentication test failed.
if changed to 4096, then the same test code gives both parties are authenticated.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.