Skip to content

dds2333/SM4

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 

Repository files navigation

SM4

1.C#实现的国密SM4,基于WPF和BouncyCastle算法库;
2.核心算法实现参考网上大佬的代码并调试改错,目前实现将密钥不足或超过16字节(128位,SM4算法的规定的密钥长度)处理成16字节;
3.实现的加密模式有CBC和ECB两种,其中ECB模式解密时对于不正确的密钥还没实现判断,导致解密出来的结果与明文不一致;
4.CBC模式的初始向量iv写死在代码中为了保证关闭程序后再可以解密成功,随机生成iv也可以,只是目前还不能实现CBC模
式下加密完成关闭程序后再打开程序解密成功;
5.想到解决方案,将iv写入加密文件,解密时读取出来,后续更新

更新:
1.已解决两种模式解密时密钥不正确的判断;
2.CBC 模式 iv 的问题已解决,通过加密时同密文一起写入保存到密文文件,解密时读取出来,从而保证密文随机以及加密之后关闭程序可以再解密;
3.程序只是简单实现了加解密,有需要的可以参考进一步开发

注:
ECB模式的代码以及注释有差错,将 EBC 改为 ECB
Bouncycastle已经实现了 SM2、SM3、SM4 算法,实际运用参考BC库吧

C#中调用Bouncycastle的SM4加密算法:
拿CBC模式来说,需要提供 key、iv、明文,对于 key,可以使用 SM3 算法对其进行哈希截取一半的值作为实际运算中的密钥(可再使用伪随机类 SecureRandom 生成随机数拼接输入的 key ,增加随机性),iv也可以使用 SecureRandom 来生成,不过为了能解密加密后的文件,应把 iv 连同密文一起写入文件。

另外,BC 库的 Hex.Encode() 与 Hex.Decode() 在加解密的时候会经常用到,两者可实现字符串在16进制字符与原字符之间的转换;执行 Hex.Encode() 时,转换后的字符串长度比原字符串长度多一倍。

代码示例:

SM3:

string key_str="wohaicai"  
byte[] key_tmp = Encoding.Default.GetBytes(key_str);
byte[] digest;
SM3Digest md = new SM3Digest();
md.BlockUpdate(key_tmp, 0, key_tmp.Length);
digest = new byte[md.GetDigestSize()];
md.DoFinal(digest, 0);

SM4:

//加密  
byte[] plaintext = Encoding.ASCII.GetBytes("caiji");  
byte[] keyBytes = Encoding.ASCII.GetBytes("0123456789ABCDEF");  
byte[] iv = Encoding.ASCII.GetBytes("0123456789ABCDEF");  
KeyParameter key = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);  
ParametersWithIV keyParamWithIv = new ParametersWithIV(key, iv);  
IBufferedCipher inCipher = CipherUtilities.GetCipher("SM4/CBC/PKCS7Padding");  
inCipher.Init(true, keyParamWithIv);  
byte[] cipher = inCipher.DoFinal(plaintext);  
//解密  
byte[] cipher=...;//比如从文件读取  
byte[] keyBytes = Encoding.ASCII.GetBytes("0123456789ABCDEF");  
byte[] iv = Encoding.ASCII.GetBytes("0123456789ABCDEF");  
KeyParameter key = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);  
ParametersWithIV keyParamWithIv = new ParametersWithIV(key, iv);  
IBufferedCipher inCipher = CipherUtilities.GetCipher("SM4/CBC/PKCS7Padding");  
inCipher.Init(false, keyParamWithIv);  
byte[] plain = inCipher.DoFinal(cipher);

About

C#实现的国密SM4,基于WPF

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages