A5的原理及python实现

小编 2026-06-18 阅读:735 评论:0
最近要做密码学课程设计,每做一个密码就当复习一下,把算法原理啥的都过一遍吧 简介 这个是用于GSM系统的序列密码算法,A5的特点是效率高,适合硬件上高效实现。 加密过程 A5 / 1基于三个...

最近要做密码学课程设计,每做一个密码就当复习一下,把算法原理啥的都过一遍吧

简介

这个是用于GSM系统的序列密码算法,A5的特点是效率高,适合硬件上高效实现。

加密过程

  1. A5 / 1基于三个线性反馈移位寄存器LFSR的组合,三个寄存器的长度分别为 19 22 23位,然后产生一个114位的秘钥流。因此首先输入8个字节的秘钥去填充三个寄存器的总长也就是64位。
  2. 每次获取各寄存器的最后一位相互异或一下再与明文进行异或。从这一点还是可以看出关键点在于秘钥,异或了两遍原信息一致,所以加密解密都是一样的算法了。
  3. 然后根据寄存器的某一位决定是否需要对某个储存器进行移位,存在的数据多的决定

引用维基百科的一个图,这个图很好的揭示了加密的流程

\"FyME6I.png\"

总结要注意的加密的几个点:

产生秘钥流

  1. 根据8位秘钥产生的64位二进制填充寄存器
  2. 输出秘钥流,每一位都遵循Z1[18]^Z2[21]^Z3[22]这样的流程,我们需要注意的是这里讲序列密码的时候用+表示的都是异或
  3. 然后就经过114轮迭代,就可以产生114位秘钥啦

寄存器反馈

遵循“服从多数”的原则,从每个寄存器里面取出一个中间位(上图标黄的位置)进行运算,取出的3个中间位里面至少有两个1,则中间位为1的就进行移位,为0的就不移位,反之至少两个为0,则为0的进行一次位移,为1的就不移位了,保证了每次至少有了两个LFSR被驱动移位了。

生成的补充值

补充值由某些抽头位进行异或运算的结果决定,运算结果为1则补充为1,否则补充0,3个LFSR里的抽头位如下图,但是补充的前提是又寄存器反馈决定的

\"FyG33F.png\"

python实现:

# -*- coding: utf-8 -*-
# Author:0verWatch

X = \'\'
Y = \'\'
Z = \'\'

import base64
import re


def str2bin(str_mess):
    res = \"\"
    for i in str_mess:
        tmp = bin(ord(i))[2:].zfill(8)
        res += tmp
    return res



def bin2str(bin_mess):
    res = \"\"
    tmp = re.findall(r\'.{8}\',bin_mess)
    for i in tmp:
        res += chr(int(i,2))
    return res


def LFSRinit(): #用64bit密钥初始3个移位寄存器,分别是19,22,23位
    global X
    global Y
    global Z
    key = input(\"请输入8位秘钥\\n\")
    while len(key) != 8:   #限定只能是8位,然后生成64位的二进制流
        key = input(\"请输入8位秘钥\\n\")
    key_bin_str = \"\"
    for i in key:
        tmp = bin(ord(i))[2:].zfill(8)
        key_bin_str += tmp
    X = key_bin_str[0:19]
    Y = key_bin_str[19:41]
    Z = key_bin_str[41:]
    # print(\"X\"+X)
    # print(\"Y\"+Y)
    # print(\"Z\"+Z)



def xor(bin_str,bin_key): #输入的字符串的二进制流
    res = \"\"
    for i in range(len(bin_str)):
        if bin_str[i] == bin_key[i]:
            res += \'0\'
        else:
            res += \'1\'
    return res


def create_key():
    global X
    global Y
    global Z
    LFSRinit()
    res = \"\"
    for i in range(114):   # A5 / 1用于为每个突发产生114比特的密钥流序列
        # a = X[-1]
        # b = Y[-1]
        # c = Z[-1]
        g  = int(X[-1]) ^ int(Y[-1]) ^ int(Z[-1])
        res += str(g)  #用最后一位异或产生秘钥流
        x =  str(int(X[13]) ^  int(X[16]) ^ int(X[17]) ^ int(X[18]) ^ 1)               #候选位的值
        y =  str(int(Y[20]) ^ int(Y[21]) ^ 1)
        z = str(int(Z[7]) ^ int(Z[20]) ^ int(Z[21]) ^ int(Z[22]) ^ 1)
        #选择的钟控位
        c_x = int(X[8])
        c_y = int(Y[10])
        c_z = int(Z[10])
        if (c_x + c_y + c_z) >= 2:#多数的占优
            choice = \'1\'
        else:
            choice = \'0\'
        if str(c_x) == choice:
            X = x + X[:-1] #隐式位移,这里是不包含最后一位的
        if str(c_y) == choice:
            Y = y + Y[:-1]
        if str(c_z) == choice:
            Z = z + Z[:-1]
        # print(\"X\"+X)
        # print(\"Y\"+Y)
        # print(\"Z\"+Z)
    # print(res)
    return res

def a5_encode(mess):
    bin_mess = str2bin(mess)
    bin_key = create_key()
    bin_cipher = \"\"
    #print(len(bin_mess))
    if len(bin_mess) % 114 == 0:
        for i in range(0, len(bin_mess), 114):
            bin_cipher += xor(bin_mess, bin_key)
    elif len(bin_mess) > 114:
        j = 0
        for i in range(len(bin_mess)):
            bin_cipher += str(int(bin_mess[i]) ^ int(bin_key[i]))
            j += 1
            if j == 114:
                j = 0
    else:
        for i in range(len(bin_mess)):
            bin_cipher += str(int(bin_mess[i]) ^ int(bin_key[i]))
    print(\"二进制密文\" + bin_cipher)
    print(\"十六进制密文\"+hex(int(bin_cipher,2)))
    str_cipher = bin2str(bin_cipher)
    print(base64.b64encode(str_cipher.encode(\'utf-8\')))





def a5_decode(bin_mess):
    bin_key = create_key()
    bin_cipher = \"\"
    # print(len(bin_mess))
    if len(bin_mess) % 114 == 0:
        for i in range(0, len(bin_mess), 114):
            bin_cipher += xor(bin_mess, bin_key)
    elif len(bin_mess) > 114:
        j = 0
        for i in range(len(bin_mess)):
            bin_cipher += str(int(bin_mess[i]) ^ int(bin_key[i]))
            j += 1
            if j == 114:
                j = 0
    else:
        for i in range(len(bin_mess)):
            bin_cipher += str(int(bin_mess[i]) ^ int(bin_key[i]))
    str_cipher = bin2str(bin_cipher)
    print(\"解密后的结果:\"+str_cipher)



def get_info():
    choice = input(\"1.加密\\n2.解密\\n\")
    if choice == \'1\':
        message = input(\"输入你的信息\\n\")
        a5_encode(message)
    elif choice == \'2\':
        bin_message = input(\"输入你的信息\\n\")
        a5_decode(bin_message)
    else:
        print(\"请重新输入\")

if __name__ == \'__main__\':
    while True:
        get_info()

安全性

其实这个算法的关键点还是落在了秘钥的长度,体现在其寄存器的长度上,太短了,所以现在已知明文攻击法对这个算法的攻击是先确定其中两个寄存器的初始值再计算出另外一个,所以要想改进就是采用更长的线性反馈寄存器了。。。。。

版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
标签列表