使用替换-置换网络(SP-network)的加密模型
我们使用理论示例研究组织现代加密系统的原则。
任务说明
大多数现代信息系统使用AES密码(或类似)来加密消息。 这些密码是基于代换-置换网络(SP-network)。
如果您只需要加密或解密消息,Julia有类似的库
AES.jl,允许您加密和解密字节序列。
这里提出的算法不一定是可靠的密码。 这种密码可以对S和P块参数做出正确的选择,以及生成圆形密钥并将其添加到密文的最佳功能,并且还有标准中描述的其他附加机制。 我们只是在创建一个训练示例,它在某些方面便于分析和细化。
模型的一般视图
基于SP网络的密码接收一个数据块和一个密钥作为输入,并执行几轮由块中位的交替替换和置换阶段组成。
# Загрузим модель, если она еще не открыта на холсте
if "sp_net_cipher_model" ∉ getfield.(engee.get_all_models(), :name)
engee.load( "$(@__DIR__)/sp_net_cipher_model.engee");
end
model_data = engee.run( "sp_net_cipher_model" );
println( "Количество ошибок передачи: ", convert(Int, model_data["Кол-во ошибок"].value[end]) )
接下来,我们将展开模型的每个块,看看一个单独的回合是如何工作的。
具有三轮加密的模型
如果你打开每个子系统,你可以得到一个非常直观的表示每轮算法的工作(模型 sp_net_cipher_model_3R_expand).
它允许您查看每个阶段的设置,并检查如果通配符或排列块的设置不一致会发生什么。
让我们运行这个模型并检查消息是否以相同的字节传输。 AAAAAAAA 生成不同字节的密文:
# Загрузим модель, если она еще не открыта на холсте
if "sp_net_cipher_model_3R_expand" ∉ getfield.(engee.get_all_models(), :name)
engee.load( "$(@__DIR__)/sp_net_cipher_model_3R_expand.engee");
end
model_data = engee.run( "sp_net_cipher_model_3R_expand" );
source_message = collect(model_data["Блок сообщения"]).value
cipher_text = UInt16.(collect(model_data["Зашифрованный блок"]).value)
received_message = UInt16.(collect(model_data["Расшифрованный блок"]).value)
source_bytes = vcat( reverse.([reinterpret( UInt8, [UInt16(c)]) for c in source_message])... )
cipher_bytes = vcat( reverse.([reinterpret( UInt8, [UInt16(c)]) for c in cipher_text])... )
received_bytes = vcat( reverse.([reinterpret( UInt8, [UInt16(c)]) for c in received_message])... )
println( "Отправленное сообщение: ", join( vcat( string.(source_bytes, base=16)... ), " " ) )
println( "Зашифрованное сообщение: ", join( vcat( string.(cipher_bytes, base=16)... ), " " ))
println( "Полученное сообщение: ", join( vcat( string.(received_bytes, base=16)... ), " " ) )
println( "Отправленная строка: ", String( source_bytes ))
println( "Полученная строка: ", String( received_bytes ))
请注意,密文从块17开始重复自己。
单向密码模型
如果我们将网络简化为单轮,模型将如下所示:
我们看到SP网络的所有常用元素。:
*将密钥位与明文位混合的功能(XOR),
*接受位值的替换块(Bool)输入向量,
*位置换块,其接受作为输入的先前操作的四个组合结果的向量。
如果s-和P-块的所有参数都设置正确,那么我们在输出端得到与输入端相同的消息。
# Загрузим модель, если она еще не открыта на холсте
if "sp_net_cipher_model_1R" ∉ getfield.(engee.get_all_models(), :name)
engee.load( "$(@__DIR__)/sp_net_cipher_model_1R.engee");
end
model_data = engee.run( "sp_net_cipher_model_1R" );
让我们检查发送和接收的消息。:
source_message = collect(model_data["Блок сообщения"]).value
cipher_text = UInt16.(collect(model_data["Зашифрованный блок"]).value)
received_message = UInt16.(collect(model_data["Расшифрованный блок"]).value)
source_bytes = vcat( reverse.([reinterpret( UInt8, [UInt16(c)]) for c in source_message])... )
cipher_bytes = vcat( reverse.([reinterpret( UInt8, [UInt16(c)]) for c in cipher_text])... )
received_bytes = vcat( reverse.([reinterpret( UInt8, [UInt16(c)]) for c in received_message])... )
println( "Отправленное сообщение: ", join( vcat( string.(source_bytes, base=16)... ), " " ) )
println( "Зашифрованное сообщение: ", join( vcat( string.(cipher_bytes, base=16)... ), " " ))
println( "Полученное сообщение: ", join( vcat( string.(received_bytes, base=16)... ), " " ) )
println( "Отправленная строка: ", String( source_bytes ))
println( "Полученная строка: ", String( received_bytes ))
创建圆形键
创建圆键的算法组织如下:
*形成密钥的字节序列被分成64位块。
*块重叠(关键 d0 9a d0 bb d1 8e d1 87 生成块 d0 9a d0 bb, 9a d0 bb d1, d0 bb d1 8e 等。)
*密钥循环使用
64位密钥块被分成4个每个16位的圆形密钥(顺序),其中我们只使用前三个圆形密钥。
使用模型的注意事项
解释或规划模型更改时应考虑以下功能::
*消息和密钥循环传递给模型,永远不会结束。,
*一个完整的工作周期与一个单元在一个模拟周期中执行,没有延迟
因此,在顶层,我们不使用位的向量,而是使用数字。 UInt16, UInt32 等。,
输入消息和轮键被送入模型以16位的块为单位,每轮的所有四个S块接受4位的块作为输入,以及向量为16二进制位的P块,
*s块和P块内部的置换参数不是取自码本,而是由运算产生的 shuffle 与指定 seed.
*消息以非重叠块传输到算法,关键块由偏移量为一个字节的窗口生成。
结论
我们创建了一个模型,允许我们使用SP网络研究消息加密的所有阶段,并对此算法的体系结构进行任何更改,而无需深入研究技术编程问题。