注意:以下是我花费两周时间参考go语言写出来的哦
1、创建srp6a.js和srp6aFunction.js. 一个用来实现srp6a算法,一个用来存公共函数。代码地址:
github地址:https://github.com/ying2025/Spr6a
2、下载big-integer和hash运算的包。下载链接地址分别为:https://www.npmjs.com/package/big-integer 和 https://www.npmjs.com/package/hash.js
其中有一些简单的说明,可根据自己的需要去下载。
3、在引入rp6a.js中引入hash, bigInt,commonFun。
var hash = require('hash.js'); // 引入Hash
var bigInterger = require("big-integer"); // 引入大整型
var commonFun = require('./srp6aInterface.js'); // 引入公共函数部分
4、定义全局变量
var bigInt = bigInterger(0);//初始化一个大整型
var randomSize = 512/2/8; // 随机数
var MinSaltSize = 16; // salt的最小
var nil = ""; // err为空
var arrnil = []; //数组为空
var srv = {}; // Server
var cli = {}; // client
5、构造一个Server和Client的公共变量的字面量,如下图所示:其中关于这些变量的具体含义参考:http://www.cppblog.com/Jedimaster/archive/2006/10/14/13674.aspx和http://www.aichengxu.com/os/1659958.htm。
6、定义Server和Client共有的一些方法,例如生成随机数、设置hash方式、初始化参数、数组与数组之间的拷贝、生成Salt等。
拷贝时要采用小端对齐方式。将前面的填充。
计算U
计算M1
M1验证通过后计算M2
7、定义Server的字面量,然后将srp6aBase和Srp6aServer拷贝给对象srv,然后为srv设置hash的方式和初始化参数。其中iv: bigInterger(0),这样初始化目的是为了判断iv是不是为0。
用b派生出B,b为16进制的字符串,所以bigInterger(b, 16)可以直接这样用。commonFun.bigisZero(i3)就是判断i3的value是否为0的。
srv._B = new Array(srv.byteLen);
var b_iN = bigInterger(i3).toString(16);
var v_iN = commonFun.Str2Bytes(b_iN);
padCopy(srv._B, v_iN);
上面一部分代码主要是讲bigInt类型的i3转为数组,然后copy给srv._B
随机生成B
计算S,其中var iu = bigInterger.fromArray(srv._u, 256); 官方文档给的是10进制和2进制,这里需要用到256进制的,所以第二个参数是256.
8、Client字面量定义和初始化,以及设置User's salt
9、计算x以及V。注意hash的运算。这一点吃了很大的亏哦。SHA1(identity | ":" | pass)相当于identity 、:、pass拼接后做hash运算。SHA1(salt | SHA1(identity | ":" | pass))相当于salt和
SHA1(identity | ":" | pass)做hash运算。这一点一定要理解哦。
10、设置Client的a,B
生成随机数A
11、Client计算S
12、Srp6a验证流程如下:
13、测试部分数据
var N = "EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C" +
"9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE4" +
"8E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B29" +
"7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A" +
"FD5138FE8376435B9FC61D2FC0EB06E3";
var hexSalt = "BEB25379D1A8581EB5A727673A2441EE";
var a = "60975527035CF2AD1989806F0407210BC81EDC04E2762A56AFD529DDDA2D4393";
var b = "E487CB59D31AC550471E81F00F6928E01DDA08E974A004F49E61F5D105284D20";
// console.log('aaa', a)
var id = "alice";
var pass = "password123";
var salt =commonFun.Str2Bytes(hexSalt);// // console.log(hash.utils.toArray(hexn));
// console.log("salt", salt);
// N = commonFun.Str2Bytes(hexn);
// commonFun.SetBytes(srv,N)
// console.log(commonFun.SetBytes(srv,N));
var sServer = NewServer(2, N, 1024,"SHA1");
var s = NewClient(2,N,1024,"SHA1");
// console.log(cli);
SetIdentity(id, pass); // 设置cli的id,pass
SetSalt(salt); // 设置cli的salt
var v= ComputeV(); // 计算cli的_v
// console.log(cli._v)
SetV(v); // src设置iv
var A = set_a(a) // cli设置a
SetA(A); // srv设置A;
var B = set_b(b); // srv设置b
SetB(B); // cli设置B
// // console.log(B)
var S1 = ClientComputeS(); // 计算cli的S
var S2 = ServerComputeS(); // 计算cli的S
// bigInterger(S1).compare(S2);
// console.log(S1.toString(16))
// console.log("------------------")
// console.log(S2.toString(16))
// var M1 = ComputeM1(cli);
// console.log(M1)
ComputeM2(srv);
// console.log(M1)