标签: 算法

  • 加密算法简介(含国密)

    国际算法

    • DES 旧的对称加密算法,已废弃
    • AES 新的对称加密算法,用于取代DES
    • AES-GCM 加密的同时提供消息验证,密文和验证码(MAC)一起发送,也就是AEAD,其它不带GCM后缀的AES算法不支持AEAD,ipsec和tls1.2,1.3都支持gcm模式
    • Blowfish 对称加密,已废弃
    • chacha20 流式对称加密,使用256位密钥长,对应AES256,安全性与AES相当或略优于AES,纯软件件计算比AES快3倍,比硬件AES慢1倍。这个算法以后用的会越来越多,在没有AES指令集的设备上chacha20是首选算法。由RFC 8439定义。
    • chacha20-poly1305 chacha20的AEAD版
    • RC4 对称加密,特点是速度非常快,比硬件加速的AES还快,已废弃
    • RSA 非对称加密算法,可用于消息加密,消息签名,密钥交换(低于1024位不安全)
    • ECC 非对称加密算法,另外用于密钥交换时用ECDH,用于消息签名时用ECDSA,一般不直接用于加密,根据不同的密钥长度分为P-192, P-224, P-256, P-384 和 P-521。
    • curve25519 非对称加密算法,蒙哥马利曲线,另一种椭圆曲线,256位的密钥长度,比ECC速度更快,更安全
    • curve448 非对称加密算法,448位的密钥长度,curve25519的加强版,安全性更高,但速度没有curve25519快
    • DSA 非对称加密算法,只能用于消息签名,但是用于签名时相比RSA也没有啥优势,所以使用并不多
    • ECDSA DSA的ECC版,ECC一般不直接用于签名,目前基于ECC的数字签名算法就是ECDSA
    • EDDSA 基于爱德华兹曲线的签名算法,速度更快,更安全,用于取代ECDSA,因为NIST有往算法里掺沙子的前科。
    • ED25519 是EDDSA的curve25519实现,密钥长度是256位
    • ED448 是EDDSA的curve448实现,密钥长度448位
    • DH 非对称加密算法,只能用于密钥交换
    • ECDH DH的ECC版,ipsec中DH group 19,20,21使用的是ECDH,其它使用的是DH
    • X25519,X448 ED版的DH算法,分别对应curve25519,curve448,ipsec中对应dh31和dh32
    • DHE,ECDHE 使用临时公私钥的DH,ECDHE算法,提供PFS能力,TLS1.3上PFS是必选的,IPsec可选支持PFS
    • MD5 散列算法,128位,速度很快,已废弃
    • SHA-1 散列算法,160位,已废弃
    • SHA-2(SHA256-SHA512) 散列算法
    • SHA-3(SHA3-256-SHA3-512) 散列算法,长度与sha2一致但使用了不同的算法,是SHA2的备选。目前并没有消息说SHA3比SHA2更安全,只是没有与SHA2相同的弱点。
    • HMAC 加了密码的散列算法,即可以用于散列,也可以用于身份验证(密码不一样,散列结果不一样),HMAC可以与任意其它散列算法一起使用,这样散列算法也实现了AEAD

    国密算法:

    • SM1 相当于AES128,算法不公开,用于小数据量的加解密
    • SM2 基于ECC,相当于ECC256,ECDH,ECDSA,可用于加密,签名,密钥交换,USG6525E防火墙支持使用sm2进行身份认证
    • SM3 相当于SHA-256,但比sha-256g速度慢,支持MAC的版本为HMAC-SM3,USG6525E防火墙不支持IKEV2的完整性验证,但支持sm3用于IKEV1的完整性验证
    • SM4 与SM1一样都是对称加密,用于大数据量的加解密,也可以支持GCM模式(AEAD),USG6525E防火墙中可用于IPsec的数据加密,但不支持GCM模式,所以还需要另外配置完整性验证(使用GCM模式时esp authentication-algorithm不再生效)
    • SM7 与SM1一样,都是128位密钥和分组,主要用于非接触式IC卡,算法不公开
    • SSF33 对称加密,使用较少,算法不公开
    • SM9 非对称加密,使用用户标识(手机号,姓名,email地址)作为公钥,免去了证书创建,使用更方便,属于轻量级的非对称加密
    • ZUC 流式对称加密,可支持AEAD,已成为LTE标准

    注意:
    ECC256的安全性相当于RSA3072
    ECC256的破解难度相当于AES128,对称密码的破解难度要比非对称密码高
    SECP定义的曲线以r1作为后缀的与NIST定义的曲线是相同的,比如secp256r1等于nist p-256,secp38441等于nist p-384,这个定义secp曲线的seca组织是NIST的马甲吗?
    这里可以查看各个曲线的参数定义
    https://neuromancer.sk/std/secg/secp256r1
    secp256k1不是由nist定义的,比特币用的也是这个算法
    brainpool系列曲线是由rfc5639定义的,比nist的更安全,但是速度要慢得多,所以一般用ed25519的多
    爱德华兹曲线相关的ed25519,x25519,ed448,x448是由IETF定义的
    TLS1.3提供了对cure25519,cure448,AEAD的支持,USG6525E支持AEAD但不支持cure25519和cure448
    sha1,sha2,sha3,dsa,ecdsa,aes,ecc NIST P-xxx,des,hmac等算法都是由nist定义的
    关于ipsec中的dh组应该是由ietf自己定义的,可以参考RFC6071,国密算法中没有定义dh组
    各种椭圆曲线算法中只有国密的SM2是能直接加解密数据的,NIST,SECG,IETF定义的ECC和ED25519都不支持加解密数据,而只能用于签名和密钥交换
    2012年起中国国家密码局陆续发布国密算法,2013发生棱境门事件并爆出了Dual_EC_DRBG后门
    中国国家密码局2014年发布GM/T 0022-2014 IPSec VPN技术规范,2023年发布了GM/T 0022-2023 IPSec VPN技术规范
    中国国家密码局发布的商秘(SM)算法不能用于处理国家秘密,只能用于处理商业秘密
    AEAD把认证数据分为加密数据和非加密数据(关联数据),通过一个MAC保证加密部分和非加密部分均未篡改。通常IP数据包内容是需要加密的数据,IP数据包头是不需要加密的信息。

    Views: 13

  • Python数据等比连续抽样算法

    numpy里面自带了几种抽样算法,但都是随机抽样,我这里要做的是等比连续抽样,就是对原始数据从前到后按固定的间隔固定的顺序去抽样数据。
    方法一:
    把列表分成n个子组,从每个子组中再抽取一个数作为样本

    def evenly_divide_list(lst, num_groups):
        """按顺序分隔列表为指定数量的子组
        Args:
            lst (list): 列表
            num_groups (int): 分隔次数
        Returns:
            list: 返回子列表的集合
        """
        quotient, remainder = divmod(len(lst), num_groups)
        group_sizes = [quotient] * num_groups
        for i in range(remainder):
            group_sizes[i] += 1
        groups = []
        i = 0
        for size in group_sizes:
            groups.append(lst[i:i + size])
            i += size
        return groups
    data = [1, 2, 4, 5]
    count = 3
    sample_group = evenly_divide_list(data, count)
    for i in range(len(sample_group)):
            print(sample_group[i][0])
    

    方法二:
    对列表索引分成固定的间隔然后进行进行四舍五入

    def extract_elements(lst, num_elements):
        """按顺序均匀抽样元素
        Args:
            lst (list): 列表
            num_groups (int): 抽样次数
        Returns:
            list: 返回抽样元素的集合
        """
        if num_elements > len(lst):
            return lst
        step = len(lst) / num_elements
        return [lst[round(i * step)] for i in range(num_elements)]
    data = [1, 2, 4, 5]
    count = 3
    sample_group = extract_elements(data, count)
    for i in range(len(sample_group)):
            print(sample_group[i])
    

    第一种方法是把不能整分的元素全部加到最前面几个组中,这样前面的组就比后面的组抽样间隔更大
    第二种方法则是把不能等分的元素按四舍五入法分散在不同的段中,这种方法显然抽样更均匀,而且方法一多了一个数组切分过程,算法复杂度更大,所以推荐用方法二。

    Views: 2