KeeLoq加密算法

KeeLoq加密算法
四个字节的对称加密算法,用于部分通讯协议中,对关键信息加密处理。
目前使用较多的是上位机加密,硬件解密,所以以下C语言有加解密,C#和nodejs的有加密。

最近研究了一种新的文案,通讯登录时校验,可以起到防窃听,防篡改作用,通讯过程中完全不用再加密。

以下为C语言写法

#define KeeLoq_NLF    0x3A5C742E
#define bit(x,n)    (((x)>>(n))&1)
#define g5(x,a,b,c,d,e)  (bit(x,a)+bit(x,b)*2+bit(x,c)*4+bit(x,d)*8+bit(x,e)*16)

// 加密
u32  KeeLoq_Encrypt (u32 data, u32 key)
{
  u32  x = data, r;
  
  for (r = 0; r < 528; r++)
  {
    x = (x>>1)^((bit(x,0)^bit(x,16)^(u32)bit(key,r&63)^bit(KeeLoq_NLF,g5(x,1,9,20,26,31)))<<31);
  }
  return x;
}

// 解密
u32 Keeloq_Decrypt(u32 data,u32 key)
{
  u32  x = data, r;
  for (r = 0; r < 528; r++)
  {
     x = (x<<1) ^ (bit(x,31)) ^ (bit(x,15)) ^ (bit(key,(15-r)&63)) ^ bit(KeeLoq_NLF,g5(x,0,8,19,25,30));
  }
  return x;
}

c#

  /// <summary>
    /// KeeLoq加密算法
    /// </summary>
    public class KeeLoq
    {
        /// <summary>
        /// 固定公共密钥
        /// </summary>
        private const UInt64 KeeLoq_NLF = 0x3A5C742E;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="x"></param>
        /// <param name="n"></param>
        /// <returns></returns>
        private static UInt64 bit(UInt64 x, int n)
        {
            return (x >> n) & 1;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="x"></param>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="c"></param>
        /// <param name="d"></param>
        /// <param name="e"></param>
        /// <returns></returns>
        private static UInt64 g5(UInt64 x, byte a, byte b, byte c, byte d, byte e)
        {
            return bit(x, a) + bit(x, b) * 2 + bit(x, c) * 4 + bit(x, d) * 8 + bit(x, e) * 16;
        }

        /// <summary>
        /// 加密算法
        /// </summary>
        /// <param name="data"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static byte[] KeeLoq_Encrypt(byte[] data, byte[] key)
        {
            Array.Reverse(data);
            Array.Reverse(key);
            UInt32 userData = BitConverter.ToUInt32(data, 0);
            UInt32 uKey = BitConverter.ToUInt32(key, 0);
            UInt64 uResult = KeeLoq_Encrypt(userData, uKey);
            byte[] resultBytes = BitConverter.GetBytes(uResult);
            byte[] outBytes = new byte[4];
            Buffer.BlockCopy(resultBytes, 0, outBytes, 0, 4);
            Array.Reverse(outBytes);
            return outBytes;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static UInt64 KeeLoq_Encrypt(UInt32 data, UInt32 key)
        {
            UInt64 x = data;
            int r;

            for (r = 0; r < 528; r++)
            {
                x = (x >> 1) ^ ((bit(x, 0) ^ bit(x, 16) ^ bit(key, r & 63) ^ bit(KeeLoq_NLF, (int)(g5(x, 1, 9, 20, 26, 31)))) << 31);
            }
            return x;
        }

        / <summary>
        / 
        / </summary>
        / <param name="data"></param>
        / <param name="key"></param>
        / <returns></returns>
        //public UInt64 KeeLoq_Decrypt(UInt32 data, UInt32 key)
        //{
        //    UInt64 x = data;
        //    int r;

        //    for (r = 0; r < 528; r++)
        //    {
        //        x = (x << 1) ^ bit(x, 31) ^ bit(x, 15) ^ bit(key, (15 - r) & 63) ^ bit(KeeLoq_NLF, (int)g5(x, 0, 8, 19, 25, 30));
        //    }
        //    return x;
        //}
    }

nodejs

/*****************************
 * KeeLoq加密算法
 *
 ****************************/
'use strict';
const Long = require("long");
const KeeLoq_NLF = Long.fromBytesBE([0x00, 0x00, 0x00, 0x00, 0x3A, 0x5C, 0x74, 0x2E], false);

function bit(x, n) {
    return x.shiftRightUnsigned(n).and(1);
}

function g5(x, a, b, c, d, e) {
    //return bit(x, a) + bit(x, b).multiply(2) + bit(x, c).multiply(4) + bit(x, d).multiply(8) + bit(x, e).multiply(16);
    return bit(x, a).add(bit(x, b).multiply(2)).add(bit(x, c).multiply(4)).add(bit(x, d).multiply(8)).add(bit(x, e).multiply(16));
}

/**
 * 加密
 * @param data
 * @param key
 */
function encrypt(data, key) {
    let x = data;
    let r = 0;
    for (r = 0; r < 528; r++) {
        // x = (x >> 1) ^ ((bit(x, 0) ^ bit(x, 16) ^ bit(key, r & 63) ^ bit(KeeLoq_NLF, (g5(x, 1, 9, 20, 26, 31)))) << 31);

        let y = g5(x, 1, 9, 20, 26, 31);
        //let h = (x >>> 1);
        let h = x.shiftRightUnsigned(1);
        if (h < 0) throw new Error(h);
        let j = bit(KeeLoq_NLF, y);
        if (j < 0) throw new Error(j);
        let k = bit(key, r & 63);
        if (k < 0) throw new Error(k);
        let l = bit(x, 0);
        if (l < 0) throw new Error(l);
        let m = bit(x, 16);
        if (m < 0) throw new Error(m);
        //let n = l ^ m ^ k ^ j;
        let n = l.xor(m);
        if (n < 0) throw new Error(n);
        n = n.xor(k);
        //if (n < 0) throw new Error(n);
        n = n.xor(j);
        if (n < 0) throw new Error(n);
        //if(n === 1) n = toUint(n);
        //let i = n << 31;
        //n = Long.fromValue(n);
        let i = n.shiftLeft(31);
        // if (i === -2147483648) i = 2147483648;
        if (i < 0) throw new Error(i);
        x = h.xor(i);
        x = Long.fromValue(x);
    }
    return x;
}

exports.encrypt = encrypt;


/**
 * 加密
 * @param dataBytes
 * @param keyBytes
 */
function encryptBytes(dataBytes, keyBytes) {
    let data = Long.fromBytesBE([0x00, 0x00, 0x00, 0x00, dataBytes[0], dataBytes[1], dataBytes[2], dataBytes[3]], false);
    let key = Long.fromBytesBE([0x00, 0x00, 0x00, 0x00, keyBytes[0], keyBytes[1], keyBytes[2], keyBytes[3]], false);
    let result = encrypt(data, key);
    let outBytes = Buffer.alloc(4);
    let nums = result.toBytesBE();
    outBytes[0] = nums[4];
    outBytes[1] = nums[5];
    outBytes[2] = nums[6];
    outBytes[3] = nums[7];
    return outBytes;
}

exports.encryptBytes = encryptBytes;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大鹏展翅888

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值