Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# go AES加密CBC 问题_C#_Go_Encryption_Aes_Cbc Mode - Fatal编程技术网

C# go AES加密CBC 问题

C# go AES加密CBC 问题,c#,go,encryption,aes,cbc-mode,C#,Go,Encryption,Aes,Cbc Mode,我必须将一个函数从C#移植到GO,它使用AES加密。 显然,我必须用GO得到与C# C# 密码小提琴 我用C# 使用系统; 使用System.Linq; 使用System.Security.Cryptography; 使用系统文本; 公共课程 { 公共静态void Main() { var query=“csharp->golang”; var key=Encoding.UTF8.GetBytes(“1234567890121345678901234567890123456789012”); v

我必须将一个函数从
C#
移植到
GO
,它使用
AES
加密。 显然,我必须用
GO
得到与
C#

C# 密码小提琴 我用
C#

使用系统;
使用System.Linq;
使用System.Security.Cryptography;
使用系统文本;
公共课程
{
公共静态void Main()
{
var query=“csharp->golang”;
var key=Encoding.UTF8.GetBytes(“1234567890121345678901234567890123456789012”);
var iv=Encoding.UTF8.GetBytes(“1234567890123456”);
使用(var aes=(RijndaelManaged)RijndaelManaged.Create())
{
aes.KeySize=256;
aes.Mode=CipherMode.CBC;
aes.Key=Key;
aes.IV=IV;
使用(var transform=aes.CreateEncryptor())
{
Console.WriteLine(“query=>”+query);
var toEncodeByte=Encoding.UTF8.GetBytes(查询);
Console.WriteLine(“toEncodeByte=“+ToString(toEncodeByte));
var encrypted=transform.TransformFinalBlock(toEncodeByte,0,toEncodeByte.Length);
Console.WriteLine(“encrypted=“+ToString(encrypted));
}
}
}
公共静态字符串ToString(字节[]b)
{
返回“[”+String.Join(“,b.Select(h=>h.ToString()))+”];
}
}
控制台输出
query=>csharp->golang
toEncodeByte=[99 115 104 97 114 112 32 45 62 32 103 111 108 97 110 103]
加密=[110 150 8 224 44 118 15 182 248 172 105 14 61 212 219 205 216 31 76 112 179 76 214 154 227 112 159 176 24 61 108 100]
去 密码小提琴 我准备了一个小机智
GO

主程序包
进口(
“字节”
“加密/aes”
“加密/密码”
“编码/十六进制”
“fmt”
)
func main(){
查询:=“csharp->golang”
键:=[]字节(“1234567890012345678901234567890123456789012”)
iv:=[]字节(“12345678900123456”)
如果len(键)!=32{
fmt.Printf(“密钥len必须是16。其:%v\n”,len(密钥))
}
如果len(iv)!=16{
fmt.Printf(“IV len必须是16。其:%v\n”,len(IV))
}
var加密字符串
toEncodeByte:=[]字节(查询)
fmt.Println(“查询=>”,查询)
fmt.Println(“toEncodeByte=,toEncodeByte”)
toEncodeBytePadded:=PKCS5Padding(TOENCODEBYTED,len(键))
//aes
块,错误:=aes.NewCipher(密钥)
如果错误!=零{
fmt.Println(“CBC加密失败”)
}
密文:=make([]字节,len(toencodebyte填充))
模式:=cipher.NewCBCEncrypter(块,iv)
模式.加密块(密文,加密字节)
加密=十六进制编码字符串(密文)
//aes结束
fmt.Println(“加密的”,[]字节(加密的))
}
func PKCS5Padding(密文[]字节,块大小int)[]字节{
填充:=(块大小-len(密文)%blockSize)
padtext:=字节。重复([]字节{字节(填充)},填充)
返回附加(密文、padtext…)
}
控制台输出
query=>csharp->golang
toEncodeByte=[99 115 104 97 114 112 32 45 62 32 103 111 108 97 110 103]
加密的[54 101 57 54 48 56 101 48 50 99 55 54 48 102 98 54 102 56 97 99 54 57 48 101 51 100 52 100 98 100 56 49 102 52 99 55 48 98 51 52 99 100 54 97 101 55 48 57 102 98 48 56 56 51 100 54 99 54 52]
总结 我注意到在
C#
中,输入不必与
块的大小相同
在
GO
中,如果没有填充,这似乎不起作用(因此我在
GO
代码中添加了填充),但结果不同。

获得相等的
结果的解决方案非常好

首先,两种代码的密文是相同的。但是,Golang代码中的密文转换不正确

在C代码中,
字节[]
的内容以十进制格式打印。要获得Golang代码中的等效输出,
[]字节的内容也必须以十进制格式打印,这可以通过以下方式轻松实现:

fmt.Println(“密文”,密文)
并生成以下输出:

密文[110 150 8 224 44 118 15 182 248 172 105 14 61 212 219 205 216 31 76 112 179 76 214 154 227 112 159 176 24 61 108 100]
与C代码的输出相同


在当前代码中,密文首先用以下代码编码:

encrypted=hex.EncodeToString(密文)
转换为十六进制字符串,可通过以下方式轻松验证:

fmt.Println(“加密(十六进制)”,加密)
产生以下输出:

加密(十六进制)6E9608E02C760FB6F8AC690E3DD4DBCD81F4C70B34CD69AE3709FB0183D6C64
当使用
[]字节(加密)
将十六进制字符串转换为
[]字节
时,会进行Utf8编码,该编码会将数据大小加倍,输出为:

fmt.Println(“加密的”,[]字节(加密的))
在当前代码中显示:

加密[54 101 57 54 48 56 101 48 50 99 55 54 48 102 98 54 102 56 97 99 54 57 48 101 51 100 52 100 98 100 56 49 102 52 99 55 48 98 51 52 100 54 97 101 55 48 57 102 48 49 56 51 100 54 52]

CBC是一种分组密码模式,即明文长度必须是块大小的整数倍(AES为16字节)。如果不是这样,则必须应用填充。C#代码隐式使用PKCS7填充。这就是为什么不满足长度条件的明文也会被处理的原因

相反,在Golang中,代码填充必须显式完成,这是通过实现PKCS7填充的
PKCS5Padding()
方法完成的。
PKCS5Padding()
方法的第二个参数是块大小,AES的块大小为16字节。对于此参数,实际上应传递
aes.BlockSize
。目前,
len(key)
已传递给她