商用密码应用安全性评估之密码算法详解

admin 2024年5月17日20:01:56评论11 views字数 7196阅读23分59秒阅读模式
  • 商用密码应用安全性评估(以下简称密评)之密码算法

密码算法指描述密码处理过程的一组运算规则或规程。

在GB/T 39786 《信息安全技术 信息系统密码应用基本要求》、GB/T 0115 《信息系统密码应用测评要求》的通用要求中都明确规定了:信息系统中使用的密码算法应符合法律、法规的规定和密码相关国家标准、行业标准的有关要求。

密码算法作为密评中的通用要求,所有级别的信息系统都应遵循。虽然其不作为单独的测评项而是融入到具体的指标中进行测评,但是涉及密码算法的高风险判定无缓解措施且密码算法的密码强度已加入了量化评估规则。本文将对密码算法进行详解:

  • 密码算法的分类

商用密码应用安全性评估之密码算法详解
  • 对称密码算法
对称密码算法是指加密密钥和解密密钥相同的算法,加解密时使用相同的密钥,过程对称。对称密码算法又可根据加解密步骤的不同分为分组密码算法和序列密码算法。
    一、SM4
1.算法概念
SM4是一个迭代分组密码算法,数据分组长度为128比特,密钥长度为128比特,其加密算法与密钥扩展算法都采用32轮非线性迭代结构,安全性与AES-128相当。
2.算法步骤
SM4加密过程中128比特明文分成四组,第一组直接落下,后三组与轮密 钥进行异或运算,再经过S盒及线性移位等变换,最后的输出与明文分 组一进行异或运算得到第一轮密文,如此进行32轮,将最后4轮密文值组合再经过反序变换函数得到R,才得到最终的SM4加密算法的密文。解密过程与加密过程相同,只是在迭代的时候需要将轮密钥逆序使用。具体密钥扩展算法及加密算法如图:
商用密码应用安全性评估之密码算法详解
3.算法核心代码
加密部分代码示例:
def SMJ(x):#SM4加密算法

X = [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,

    0x0, 0x0, 0x0, 0x0, 0x0, 0x0,0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,

0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]

X[0] = (x >> 96) & 0xffffffff
X[1] = (x >> 64) & 0xffffffff
X[2] = (x >> 32) & 0xffffffff
X[3] = (x >> 0) & 0xffffffff
for i in range(33):
X[i+4] = X[i]^T_(X[i+1]^X[i+2]^X[i+3]^rk[i])#轮函数

return (X[35]<<96)^(X[34]<<64)^(X[33]<<32)^X[32]

if __name__ == '__main__':
MK = int(input("请输入加密密钥: "), 16)
print(MK)
MK0=(MK>>96)&0Xffffffff
MK1=(MK>>64)&0Xffffffff
MK2=(MK>>32)&0Xffffffff
MK3=(MK>>0)&0Xffffffff
K_(MK0, MK1, MK2, MK3)
message = input('输入待加密的消息:n')
M = mpz(binascii.hexlify(message.encode('utf-8')), 16)
#x = int(input("请输入明文: "), 16)
print("密文为:{:x}".format(SMJ(M)))

运行结果:
商用密码应用安全性评估之密码算法详解
  • 非对称密码算法(公钥密码算法)
非对称密码算法的加密密钥和解密密钥不同,加密密钥可以公开称为公钥,解密密钥需要保密称为私钥,正常来说从私钥可推导出公钥,但从公钥推导出私钥在计算上是不可行的。因此非对称密码算法一般有以下三种用途:公钥加密、数字签名、密钥交换。
一、RSA
    1.算法概念
RSA是基于大整数因子分解数学问题的公钥密码算法,RSA密钥长度可选,主流值有1024、2048、3072(安全性与SM2相当)、4096等比特。
2.算法步骤
RSA具体算法步骤如下,其中C为密文、M为明文:
商用密码应用安全性评估之密码算法详解
3.算法代码
加密部分代码示例:
import gmpy2
from gmpy2 import mpz
import binascii
def gen_prime(rs):
"
""生成二进制位数为1024的随机素数"""p = gmpy2.mpz_urandomb(rs, 1024)
while not gmpy2.is_prime(p):
p = p + 1
return p
def gen_key():

"""生成密钥"""

  rs = gmpy2.random_state()
p = gen_prime(rs)
q = gen_prime(rs)
return p, q
def encrypt(e, n, message):
"
""将输入消息转换成16进制数字并加密,支持utf-8字符串"""

  M = mpz(binascii.hexlify(message.encode('utf-8')), 16)
C = gmpy2.powmod(M, e, n)
return C
def decrypt(d, n, C):
"""对输入的密文进行解密并解码"""
M = gmpy2.powmod(C, d, n)
return binascii.unhexlify(format(M, 'x')).decode('utf-8')
def main():
# 密钥生
p, q = gen_key()
n = p * q
phi = (p - 1) * (q - 1)
e = 65537
d = gmpy2.invert(e, phi)
# 输入消息

  message = input('输入待加密的消息:n')
# 加密

  C = encrypt(e, n, message)
print('16进制密文:', hex(C))
# 解密

  print('解密后的消息:', decrypt(d, n, C))
if __name__ == '__main__':

p = gen_prime(rs)
q = gen_prime(rs)
return p, q
def encrypt(e, n, message):
"
""将输入消息转换成16进制数字并加密,支持utf-8字符串"""
M = mpz(binascii.hexlify(message.encode('utf-8')), 16)
C = gmpy2.powmod(M, e, n)
return C
def decrypt(d, n, C):
""
"对输入的密文进行解密并解码"""
M = gmpy2.powmod(C, d, n)
return binascii.unhexlify(format(M, 'x')).decode('utf-8')
def main():

#密钥生成

  p, q = gen_key()
n = p * q
phi = (p - 1) * (q - 1)
e = 65537
d = gmpy2.invert(e, phi)

n = p * q
phi = (p - 1) * (q - 1)
e = 65537
d = gmpy2.invert(e, phi)

# 输入消息

  message = input('输入待加密的消息:n')
# 加密

  C = encrypt(e, n, message)
print('16进制密文:', hex(C))
# 解密

  print('解密后的消息:', decrypt(d, n, C))
if __name__ == '__main__':

# 加密

  C = encrypt(e, n, message)
print('16进制密文:', hex(C))
# 解密

  print('解密后的消息:', decrypt(d, n, C))
if __name__ == '__main__':

print('16进制密文:', hex(C))
# 解密
print('解密后的消息:', decrypt(d, n, C))
if __name__ == '__main__':

main()

运行结果:

商用密码应用安全性评估之密码算法详解

二、SM2
    1.算法概念
SM2是基于椭圆曲线离散对数问题的公钥密码算法,SM2私钥长度256比特,公钥长度512比特。
    密文长度=明文长度+96字节
    标准签名值长度为64字节,分为r和s两部分,实际签名值可能出现      69-72字节
2.算法步骤
公钥加密步骤:
设:私钥dB,公钥PB,其中PB = dB⋅G,明文M,解密后得到的明文M’,密文C,其中C由3部分拼接组成,C1 ,C2,C3,明文的比特长度为klen。
    (1)生成随机数k;(这里的k不是私钥,和ECC算法步骤中的k都是随机生成,但不作为私钥使用,因此,私钥和k在签名过程中的使用密切相关,但是它们是不同的概念。私钥用于身份认证和消息签名,而k用于防止相同消息使用相同私钥生成相同的签名值,从而增加了签名的安全性。)
    (2)计算C1 = k⋅G;
    (3)计算点N(x2 ,y2),N = k⋅PB;
    (4)计算t = KDF(x2 ||y2, klen),其中KDF是密钥派生函数,生成和明文等长的t,用于和明文异或运算;
    (5)计算C2 =M⨁ t;
    (6)计算C3 =Hash(x2 || M || y2);
    (7)拼接得到密文C =(C1 || C3|| C2)。
私钥解密阶段:
(1)拆分密文C,得到C1、C2、C3 ;
    (2)利用C1得到点N(x2,y2):N = dB⋅C1 = dB⋅k⋅G= k⋅PB;
    (3)计算t = KDF(x2||y2, klen);
    (4)计算明文M’= C2⨁ t;
    (5)检验哈希值 Hash(x2|| M || y2)是否等于C3。
    注:公钥加密算法需要双方共同知道的数据:明文长度,Hash函数,密钥派生函数。密钥派生函数KDF如图:
商用密码应用安全性评估之密码算法详解
3.算法代码
加密部分代码示例:

def encry_sm2(args, PB, M):
p, a, b, h, G, n = args # 序列解包
M_bytes = bytes(M, encoding='ascii')
print("A1:用随机数发生器产生随机数k∈[1,n-1]")
k = random.randint(1, n-1)#生成随机数k 用于生成公钥
k_hex = hex(k)[2:] # k_hex k的十六进制串形式
print("生成的随机数是:", k_hex)
print("nA2:计算椭圆曲线点C1=[k]G=(x1,y1),将C1的数据类型转换为比特串")
C1 = mult_point(G, k, p, a)print("椭圆曲线点C1=[k]G=(x1,y1)的坐标是:", tuple(map(hex, C1)))
C1_bits = point_to_bits(C1)
print("椭圆曲线点C1=[k]G=(x1,y1)的坐标的比特串形式是:", C1_bits)
print("nA3:计算椭圆曲线点S = [h]PB")
S = mult_point(PB, h, p, a)
if S == 0:
raise Exception("计算得到的S是无穷远点")
print("A3椭圆曲线点S = [h]PB的坐标是:", tuple(map(hex, S)))
print("nA4:计算椭圆曲线点[k]PB=(x2,y2),将坐标x2y2 的数据类型转换为比特串")
x2, y2 = mult_point(PB, k, p, a)print("椭圆曲线点[k]PB=(x2,y2)的坐标是:", tuple(map(hex, (x2, y2))))
x2_bits = fielde_to_bits(x2)
print("x2的比特串形式是:", x2_bits)
y2_bits = fielde_to_bits(y2)
print("y2的比特串形式是:", y2_bits)
print("nA5:计算t=KDF(x2 ∥ y2, klen),若t为全0比特串,则返回A1")
M_hex = bytes_to_hex(M_bytes)
klen = 4 * len(M_hex)
print("明文消息的比特串长度klen是:", klen)
t = KDF(x2_bits + y2_bits, klen)print("通过KDF算法计算得到的t=KDF(x2 ∥ y2, klen)是:", t)
if eval('0b' + t) == 0:
raise Exception("KDF返回了全零串,请检查KDF算法!")
t_hex = bits_to_hex(t)
print("t的十六进制表示形式是:", t_hex)
print("nA6:计算计算C2 = M ⊕ t")
C2 = eval('0x' + M_hex + '^' + '0b' + t)#"^"表示异或操作
print("计算的C2是:", hex(C2)[2:])
print("nA7:计算C3 = Hash(x2 ∥ M ∥ y2)")
x2_bytes = bits_to_bytes(x2_bits)
y2_bytes = bits_to_bytes(y2_bits)
hash_list = [i for i in x2_bytes + M_bytes + y2_bytes]
C3 = sm3.sm3_hash(hash_list)print("计算的C3 = Hash(x2 ∥ M ∥ y2)是:", C3)
print("nA8:输出密文C = C1 ∥ C2 ∥ C3")
C1_hex = bits_to_hex(C1_bits)
C2_hex = hex(C2)[2:]
C3_hex = C3
C_hex = C1_hex + C2_hex + C3_hex
print("加密得到的密文是:", C_hex)
return C_hex

钥派生函数KDF部分代码:

def KDF(Z, klen):
v = 256 # 密码杂凑函数采用SM3if klen >= (pow(2, 32) - 1) * v:
raise Exception("密钥派生函数KDF出错,请检查klen的大小!")
ct = 0x00000001
if klen % v == 0:
l = klen // v
else:
l = klen // v + 1
Ha = []
for i in range(l): # i0 klen/v-1(向上取整),l个元素
s = Z + int_to_bits(ct).rjust(32, '0') # s存储 Z || ct 的比特串形式 # 注意,ct要填充为32
s_bytes = bits_to_bytes(s) # s_bytes存储字节串形式
s_list = [i for i in s_bytes]
hash_hex = sm3.sm3_hash(s_list)
hash_bin = hex_to_bits(hash_hex)
Ha.append(hash_bin)
ct += 1
if klen % v != 0:
Ha[-1] = Ha[-1][:klen - v*(klen//v)]
k = ''.join(Ha)
return k

运行结果:

商用密码应用安全性评估之密码算法详解

商用密码应用安全性评估之密码算法详解

商用密码应用安全性评估之密码算法详解

三、安全特性
非对称密码算法(公钥密码算法)从私钥可以推导出公钥,但从公钥推导出私钥在计算上是不可行的,因此其具有以下安全特性:
  1.单向性,没有私钥的情况下从密文计算出明文在计算上是不可行的;
  2.不可区分性,对于给定的密文无法区分出其是由给定的两个明文中的哪一个加密而来;
  3.不可延展性,没有私钥的情况下无法通过简单扩展密文来构造出新的合法密文;
  • 密码杂凑算法
  密码杂凑算法是指把任意长度的输入数据转化为固定长度的输出数据的一种密码算法,该输出数据一般称为摘要值或哈希值(hash)。
   值得注意的是,当使用密码算法技术实现真实性、完整性时,单纯的密码杂凑算法并不能实现相关功能,其须与密钥一同使用,利用密码杂凑算法将一个密钥和一个消息作为输入,生成一个消息摘要作为输出,生成的摘要值称为MAC(消息认证码)。
一、SM3
    1.算法概念
SM3是M-D结构的密码杂凑算法,其分组长度为512比特,最终输出的杂凑值为256比特,安全性与SHA-256相当。
2.算法步骤
    SM3具体算法步骤如图:
商用密码应用安全性评估之密码算法详解
3.算法代码
部分代码示例:
def sm3(msg):

"""

   sm3加密主函数
:param msg: 待加密的字符串
:retur

:param msg: 待加密的字符串

:return: sm3加密后的字符串

  """

# 字符串转化为比特s_bin = str2bin(msg)
# 对消息进行填充s_fill = msg_fill(s_bin)

# 对填充后的消息进行迭代压缩

  s_sm3 = iteration_func(s_fill)
# 对于python2需要删除因长整型而引入的末尾的L字符,python3不存在该问题

  return s_sm3.upper().replace("L", "")

# 对于python2需要删除因长整型而引入的末尾的L字符,python3不存在该问题

  return s_sm3.upper().replace("L", "")

运行结果:

商用密码应用安全性评估之密码算法详解

    二、安全特性
密码杂凑算法具有以下安全特性:
    1.单向性(抗原像攻击),为一个给定的输出找出能映射到该输出的一个输入在计算上是困难;
    2.弱抗碰撞性(抗第二原像攻击),为一个给定的输入找出能映射到同一个输出的另一个输入在计算上是困难的的;
    3.强抗碰撞性,要发现不同的输入映射到同一输出在计算上是困难的;
  • 密码算法的功能实现
在密评过程中,要实现测评指标功能所要求的密码算法有所规定,具体如下图:
商用密码应用安全性评估之密码算法详解
    以上是对常用商用密码算法的分析,商用密码是用于商业环境中的一种安全措施,用于保护商业机密和敏感信息的安全。

在做商用密码测评时,应该知道商用密码算法的特点:

1. 复杂性:商用密码应该由多种不同的字符组成,包括大小写字母、数字和特殊符号等,以增加密码的强度。

2. 长度:密码的长度应该足够长,一般建议至少8个字符,但更长的密码更安全。

3. 不可预测性:密码应该是随机生成的,避免使用常见的字典词汇或者个人信息。定期更换:商用密码应定期更换,以减少密码被破解的风险。

4. 单一性:每个用户或每个账户应使用唯一的密码,避免重复使用密码。

5. 多因素认证:商用密码可以搭配其他认证方式,如指纹、身份证等,以提高安全性。

6. 密码管理软件:可以使用密码管理软件来生成和管理密码,以确保密码的安全性和易记性。

总之,商用密码是企业安全策略中的重要一环,在保护商业敏感信息和减少数据泄露方面起着至关重要的作用。

原文始发于微信公众号(瑞不可当):商用密码应用安全性评估之密码算法详解

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年5月17日20:01:56
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   商用密码应用安全性评估之密码算法详解https://cn-sec.com/archives/2050964.html

发表评论

匿名网友 填写信息