为什么AES算法会出错
Why is the AES algorithm making errors
我编写了一个AES加解密方法,但是当我加解密一个文本时,算法出错。
我做错了什么?
public class VSVerschluesselung : MonoBehaviour {
[SerializeField]
private TMP_InputField input;
[SerializeField]
private TMP_InputField output;
private byte[] schluessel = { 196, 67, 23, 195, 176, 89, 198, 17, 7, 248, 47, 232, 246, 107, 249, 252, 138, 21, 133, 226, 186, 82, 255, 199, 152, 0, 1, 173, 239, 18, 181, 238 };
private byte[] iv = { 137, 224, 26, 121, 180, 59, 150, 95, 164, 216, 57, 161, 247, 251, 68, 182 };
private Aes crypt;
public void verschluesseln () {
string text = input.text;
if (text == "" || text == null) return;
Debug.Log ("Verschlüsselung");
using (Aes crypt = Aes.Create ()) {
this.crypt = crypt;
//Maximale Keygröße auswählen
crypt.KeySize = 256;
crypt.Key = schluessel;
crypt.IV = iv;
crypt.BlockSize = 128;
crypt.Mode = CipherMode.ECB;
// Create an encryptor to perform the stream transform.
ICryptoTransform encryptor = crypt.CreateEncryptor (crypt.Key, crypt.IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream ()) {
using (CryptoStream csEncrypt = new CryptoStream (msEncrypt, encryptor, CryptoStreamMode.Write)) {
using (BinaryWriter swEncrypt = new BinaryWriter (csEncrypt)) {
//Write all data to the stream.
swEncrypt.Write (text);
}
output.text = Encoding.Unicode.GetString (msEncrypt.ToArray ());
}
}
}
crypt.Clear ();
}
public void entschluesseln () {
string inputText = input.text;
if (inputText == "" || inputText == null) return;
Debug.Log ("Entschlüsselung");
using (Aes crypt = Aes.Create ()) {
this.crypt = crypt;
//Maximale Keygröße auswählen
crypt.KeySize = 256;
crypt.Key = schluessel;
crypt.IV = iv;
crypt.BlockSize = 128;
crypt.Mode = CipherMode.ECB;
byte[] verschlText = Encoding.Unicode.GetBytes (inputText);
// Create a decryptor to perform the stream transform.
ICryptoTransform decryptor = crypt.CreateDecryptor (crypt.Key, crypt.IV);
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream (verschlText)) {
using (CryptoStream csDecrypt = new CryptoStream (msDecrypt, decryptor, CryptoStreamMode.Read)) {
using (StreamReader srDecrypt = new StreamReader (csDecrypt)) {
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
output.text = srDecrypt.ReadToEnd ();
}
}
}
}
crypt.Clear ();
}
}
输入:
1 起初神创造天地
2 大地war 荒凉空旷,深渊一片黑暗;上帝的灵在水面上盘旋。
3 上帝说:要有光!而且它 ward 亮。
4 神看光是好的war。然后上帝把光暗分开了
5又叫光明日和黑暗夜。从第一天晚上到早上 ward。
输出:
�1一开始sc����h��y��k��land earth.
2 大地war 荒凉空旷,深渊一片黑暗;上帝的灵在水面上盘旋。
3 上帝说:要有����=1��Ŀ����ƺ硬光。
4 上帝看到 I2>��Q��d����% war。然后上帝把光暗分开了
5并称光日��|��_q������为夜。从第一天晚上到早上 ward。
这里的主要错误是加密函数中的output.text = Encoding.Unicode.GetString (msEncrypt.ToArray());
和解密函数中的Unicode.GetBytes
方法。现代密文由字节而不是实际文本组成。因此,如果您将其视为字符串,那么您可能会丢失信息,因为并非所有字节都代表有效字符。或者,在这种情况下,16 位 UTF-16LE 代码单元,因为那是 Unicode
错误表示的。
如果只更改解密函数的一位输入,那么它将错误地解密整个块。代码单元或字节的丢失更糟。
备注:
- 永远不要存储
Aes
密码对象,这些是轻量级对象。只需存储密钥即可;
- 使用UTF-8,是不是比UTF-16效率更高,用得更多,甚至比小端形式的UTF-16还多;
- ECB 不采用 IV,而是使用 CBC,至少它是 CPA 安全的(如果没有明文预言机)。
- 使用 base64 或 base64url 将密文(即随机字节)转换为实际可打印字符。
- 将IV作为密文前缀(直接使用
MemoryStream
是将带有密文的IV从加密函数传递到解密函数的好方法。
维尔·埃尔福格!
我编写了一个AES加解密方法,但是当我加解密一个文本时,算法出错。 我做错了什么?
public class VSVerschluesselung : MonoBehaviour {
[SerializeField]
private TMP_InputField input;
[SerializeField]
private TMP_InputField output;
private byte[] schluessel = { 196, 67, 23, 195, 176, 89, 198, 17, 7, 248, 47, 232, 246, 107, 249, 252, 138, 21, 133, 226, 186, 82, 255, 199, 152, 0, 1, 173, 239, 18, 181, 238 };
private byte[] iv = { 137, 224, 26, 121, 180, 59, 150, 95, 164, 216, 57, 161, 247, 251, 68, 182 };
private Aes crypt;
public void verschluesseln () {
string text = input.text;
if (text == "" || text == null) return;
Debug.Log ("Verschlüsselung");
using (Aes crypt = Aes.Create ()) {
this.crypt = crypt;
//Maximale Keygröße auswählen
crypt.KeySize = 256;
crypt.Key = schluessel;
crypt.IV = iv;
crypt.BlockSize = 128;
crypt.Mode = CipherMode.ECB;
// Create an encryptor to perform the stream transform.
ICryptoTransform encryptor = crypt.CreateEncryptor (crypt.Key, crypt.IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream ()) {
using (CryptoStream csEncrypt = new CryptoStream (msEncrypt, encryptor, CryptoStreamMode.Write)) {
using (BinaryWriter swEncrypt = new BinaryWriter (csEncrypt)) {
//Write all data to the stream.
swEncrypt.Write (text);
}
output.text = Encoding.Unicode.GetString (msEncrypt.ToArray ());
}
}
}
crypt.Clear ();
}
public void entschluesseln () {
string inputText = input.text;
if (inputText == "" || inputText == null) return;
Debug.Log ("Entschlüsselung");
using (Aes crypt = Aes.Create ()) {
this.crypt = crypt;
//Maximale Keygröße auswählen
crypt.KeySize = 256;
crypt.Key = schluessel;
crypt.IV = iv;
crypt.BlockSize = 128;
crypt.Mode = CipherMode.ECB;
byte[] verschlText = Encoding.Unicode.GetBytes (inputText);
// Create a decryptor to perform the stream transform.
ICryptoTransform decryptor = crypt.CreateDecryptor (crypt.Key, crypt.IV);
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream (verschlText)) {
using (CryptoStream csDecrypt = new CryptoStream (msDecrypt, decryptor, CryptoStreamMode.Read)) {
using (StreamReader srDecrypt = new StreamReader (csDecrypt)) {
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
output.text = srDecrypt.ReadToEnd ();
}
}
}
}
crypt.Clear ();
}
}
输入:
1 起初神创造天地
2 大地war 荒凉空旷,深渊一片黑暗;上帝的灵在水面上盘旋。
3 上帝说:要有光!而且它 ward 亮。
4 神看光是好的war。然后上帝把光暗分开了
5又叫光明日和黑暗夜。从第一天晚上到早上 ward。
输出:
�1一开始sc����h��y��k��land earth.
2 大地war 荒凉空旷,深渊一片黑暗;上帝的灵在水面上盘旋。
3 上帝说:要有����=1��Ŀ����ƺ硬光。
4 上帝看到 I2>��Q��d����% war。然后上帝把光暗分开了
5并称光日��|��_q������为夜。从第一天晚上到早上 ward。
这里的主要错误是加密函数中的output.text = Encoding.Unicode.GetString (msEncrypt.ToArray());
和解密函数中的Unicode.GetBytes
方法。现代密文由字节而不是实际文本组成。因此,如果您将其视为字符串,那么您可能会丢失信息,因为并非所有字节都代表有效字符。或者,在这种情况下,16 位 UTF-16LE 代码单元,因为那是 Unicode
错误表示的。
如果只更改解密函数的一位输入,那么它将错误地解密整个块。代码单元或字节的丢失更糟。
备注:
- 永远不要存储
Aes
密码对象,这些是轻量级对象。只需存储密钥即可; - 使用UTF-8,是不是比UTF-16效率更高,用得更多,甚至比小端形式的UTF-16还多;
- ECB 不采用 IV,而是使用 CBC,至少它是 CPA 安全的(如果没有明文预言机)。
- 使用 base64 或 base64url 将密文(即随机字节)转换为实际可打印字符。
- 将IV作为密文前缀(直接使用
MemoryStream
是将带有密文的IV从加密函数传递到解密函数的好方法。
维尔·埃尔福格!