KeeLoq算法的核心思想就是用8byte密钥加密4byte明文,从而得到4byte密文或者用8byte密钥解密4byte密文,还原出原4byte明文。KeeLoq算法演算过程需要定义一个数据寄存器,用于存放4byte明文y31-y0或者4byte密文y31-y0,和一个密钥寄存器,用于存放8byte密钥k63-k0。其加密特点是运算速度快,加密性高,线性等。
var NLF = [
[
[
[
[
[],
[]
],
[
[],
[]
]
],
[
[
[],
[]
],
[
[],
[]
]
]
],
[
[
[
[],
[]
],
[
[],
[]
]
],
[
[
[],
[]
],
[
[],
[]
]
]
]
],
[
[
[
[
[],
[]
],
[
[],
[]
]
],
[
[
[],
[]
],
[
[],
[]
]
]
],
[
[
[
[],
[]
],
[
[],
[]
]
],
[
[
[],
[]
],
[
[],
[]
]
]
]
]
]
NLF[0][0][0][0][0]=0;
NLF[0][0][0][0][1]=1;
NLF[0][0][0][1][0]=1;
NLF[0][0][0][1][1]=1;
NLF[0][0][1][0][0]=0;
NLF[0][0][1][0][1]=1;
NLF[0][0][1][1][0]=0;
NLF[0][0][1][1][1]=0;
NLF[0][1][0][0][0]=0;
NLF[0][1][0][0][1]=0;
NLF[0][1][0][1][0]=1;
NLF[0][1][0][1][1]=0;
NLF[0][1][1][0][0]=1;
NLF[0][1][1][0][1]=1;
NLF[0][1][1][1][0]=1;
NLF[0][1][1][1][1]=0;
NLF[1][0][0][0][0]=0;
NLF[1][0][0][0][1]=0;
NLF[1][0][0][1][0]=1;
NLF[1][0][0][1][1]=1;
NLF[1][0][1][0][0]=1;
NLF[1][0][1][0][1]=0;
NLF[1][0][1][1][0]=1;
NLF[1][0][1][1][1]=0;
NLF[1][1][0][0][0]=0;
NLF[1][1][0][0][1]=1;
NLF[1][1][0][1][0]=0;
NLF[1][1][0][1][1]=1;
NLF[1][1][1][0][0]=1;
NLF[1][1][1][0][1]=1;
NLF[1][1][1][1][0]=0;
NLF[1][1][1][1][1]=0;
//获取source第n个位数
function getBit(source,n) {
var temp0 = 1 << n;
var temp1 = source & temp0;
if (temp1 != 0){
return 1;
}
return 0;
}
//source带进位右移
function RRC(source,c) {
if (c != 0){
source = (source >> 1) | 0x80000000;
}else {
source = (source >> 1) & 0x7fffffff;
}
return source;
}
//source带进位左移
function RLC(source,c) {
if (c != 0){
source = (source << 1) | 0x01;
}else {
source = (source << 1) & 0xFFFFFFFE;
}
return source;
}
/*
source进行加密
用8byte的key做密钥进行加密,js中long类型会精度丢失,所以把8byte的key分成低四位和高四位。
*/
function CRYPT(source,lkey,hkey) {
var c;
for (var i = 0;i < 528;i ++){
var nlf = NLF[getBit(source, 31)][getBit(source, 26)][getBit(source, 20)][getBit(source, 9)][getBit(source,
1)];
var y16 = getBit(source, 16);
var y0 = getBit(source, 0);
var index = i % 64;
var k;
if (index < 32){
k = getBit(lkey,index);
}else {
k = getBit(hkey, index);
}
var result = nlf ^ y16 ^ y0 ^ k;
if (result != 0) {
c = 1;
} else {
c = 0;
}
source = RRC(source, c);
}
return source;
}
/*
source进行解密
用8byte的key做密钥进行加密,js中long类型会精度丢失,所以把8byte的key分成低四位和高四位。
*/
function DECRYPT(source,lkey,hkey) {
var c;
for (var i = 528;i > 0; i--){
var nlf = NLF[getBit(source, 30)][getBit(source, 25)][getBit(source, 19)][getBit(source, 8)][getBit(source,
0)];
var y15 = getBit(source, 15);
var y31 = getBit(source, 31);
var index = (i-1) % 64;
var k;
if (index < 32){
k = getBit(lkey,index);
}else {
k = getBit(hkey, index);
}
var result = nlf ^ y15 ^ y31 ^ k;
if (result != 0) {
c = 1;
} else {
c = 0;
}
source = RLC(source, c);
}
return source;
}
使用:
window.onload = function () {
//key低四位
var lkey = 0x43658709;
//key高四位
var hkey = 0xefcdab21;
var source = 1520149488;
var crypt = CRYPT(source,lkey,hkey);
console.log("加密前数据:" + source);
console.log("加密后数据:" + crypt);
console.log("解密后数据:" + DECRYPT(crypt,lkey,hkey));
}
控制台输出