나는이 질문들을 여기서 보았지만 아무도 대답을 내 문제를 해결할 수 없었다. 나는 우리 서버 중 하나에 앉아 Socket과 대화하여 민감한 데이터를 해독하기위한 암호화 키를 얻기 위해 다른 프로그램을 사용하도록 작성했습니다. 아래는 제 코드입니다.AES 암호를 해독하면 "패딩이 유효하지 않으므로 제거 할 수 없습니다." 오류
소켓 서버 :
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Security.Cryptography;
namespace Netgen_Encryption_Socket
{
class Program
{
private static IPAddress ip = IPAddress.Parse("127.0.0.1");
private static string encryptionKey = "2387429837498279832";
private static byte[] IV = new byte[] { 23, 243, 29, 26, 78, 67, 23, 62, 81, 93, 12, 205, 217, 10, 216, 13 };
private static byte[] salt = new byte[] { 21, 10, 3, 26, 10, 3, 1, 49, 55, 171, 1, 51, 75, 16, 27, 14, 23, 29, 70, 16, 55, 18, 12, 2, 4, 29, 77, 52, 5, 44, 127, 164 };
private static string masterPassword = "SecretPassword";
private static bool connectionAccepted = true;
static void Main(string[] args) => Listen();
static void Listen()
{
TcpListener serverSocket = new TcpListener(IPAddress.Any, 9843);
TcpClient clientSocket = default(TcpClient);
int requestCount = 0;
serverSocket.Start();
clientSocket = serverSocket.AcceptTcpClient();
if (((IPEndPoint)clientSocket.Client.RemoteEndPoint).Address.ToString() == ip.ToString())
{
SendMessage(clientSocket, serverSocket, $"Accepted Connection from {((IPEndPoint)clientSocket.Client.RemoteEndPoint).Address}");
connectionAccepted = true;
}
else
{
SendMessage(clientSocket, serverSocket, $"Rejected Connection from {((IPEndPoint)clientSocket.Client.RemoteEndPoint).Address}");
Restart(clientSocket, serverSocket);
}
while (connectionAccepted)
{
try
{
requestCount += 1;
if (requestCount >= 4)
Restart(clientSocket, serverSocket);
string data = GetMessage(clientSocket, serverSocket);
if (data == masterPassword)
{
SendMessage(clientSocket, serverSocket, encryptionKey);
}
else
{
SendMessage(clientSocket, serverSocket, $"Invalid master password. {3 - requestCount} attempts remaining!");
if (3 - requestCount <= 0)
SendMessage(clientSocket, serverSocket, Environment.NewLine + $"Too many incorrect attempts. Connection terminated!");
}
}
catch
{
Restart(clientSocket, serverSocket);
}
}
Stop(clientSocket, serverSocket);
}
static void Restart(TcpClient client, TcpListener listener)
{
client.Close();
listener.Stop();
Listen();
}
static void Stop(TcpClient client, TcpListener listener)
{
client.Close();
listener.Stop();
}
static string GetMessage(TcpClient client, TcpListener listener)
{
NetworkStream networkStream = client.GetStream();
byte[] bytesFrom = new byte[client.ReceiveBufferSize];
networkStream.Read(bytesFrom, 0, (int)client.ReceiveBufferSize);
string data = Decrypt(bytesFrom);
data = data.Substring(0, data.IndexOf("$"));
return data;
}
static void SendMessage(TcpClient client, TcpListener listener, string message)
{
NetworkStream networkStream = client.GetStream();
byte[] sendBytes = Encrypt(message);
networkStream.Write(sendBytes, 0, sendBytes.Length);
networkStream.Flush();
}
static byte[] Encrypt(string stringToEncrypt)
{
byte[] encryptedBytes;
using(Aes AES = Aes.Create())
{
AES.Key = salt;
AES.IV = IV;
AES.Mode = CipherMode.CBC;
AES.Padding = PaddingMode.PKCS7;
var encryptor = AES.CreateEncryptor(AES.Key, AES.IV);
using(MemoryStream ms = new MemoryStream())
{
using(CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
using(StreamWriter sw = new StreamWriter(cs))
{
sw.Write(stringToEncrypt);
}
encryptedBytes = ms.ToArray();
if (!cs.HasFlushedFinalBlock)
cs.FlushFinalBlock();
}
}
}
var combined = new byte[IV.Length + encryptedBytes.Length];
Array.Copy(IV, 0, combined, 0, IV.Length);
Array.Copy(encryptedBytes, 0, combined, IV.Length, encryptedBytes.Length);
return combined;
}
static string Decrypt(byte[] bytesToDecrypt)
{
string decryptedString = null;
using(Aes AES = Aes.Create())
{
AES.Key = salt;
byte[] cipherText = new byte[bytesToDecrypt.Length - IV.Length];
Array.Copy(bytesToDecrypt, IV, IV.Length);
Array.Copy(bytesToDecrypt, IV.Length, cipherText, 0, cipherText.Length);
AES.IV = IV;
AES.Mode = CipherMode.CBC;
AES.Padding = PaddingMode.PKCS7;
var decryptor = AES.CreateDecryptor(AES.Key, AES.IV);
using(MemoryStream ms = new MemoryStream(cipherText))
{
using(CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
using(StreamReader sr = new StreamReader(cs))
{
decryptedString = sr.ReadToEnd();
}
}
}
}
return decryptedString;
}
}
}
소켓 클라이언트 : 나는 다른 유사한 게시물의 제안의 대부분을 시도
using System;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Security.Cryptography;
namespace Client_Socket_Tester
{
public partial class Form1 : Form
{
TcpClient clientSocket = new TcpClient();
private static byte[] IV = new byte[] { 23, 243, 29, 26, 78, 67, 23, 62, 81, 93, 12, 205, 217, 10, 216, 13 };
private static byte[] salt = new byte[] { 21, 10, 3, 26, 10, 3, 1, 49, 55, 171, 1, 51, 75, 16, 27, 14, 23, 29, 70, 16, 55, 18, 12, 2, 4, 29, 77, 52, 5, 44, 127, 164 };
public Form1() => InitializeComponent();
private void Form1_Load(object sender, EventArgs ev)
{
try
{
clientSocket.Connect(IPAddress.Parse("127.0.0.1"), 9843);
AppendClientMessage(" >> Connection established");
}
catch (Exception e)
{
AppendClientMessage($" >> Client Error: {e.Message}");
}
}
private void AppendClientMessage(string msg)
{
richTextBox1.Text += Environment.NewLine + msg;
}
private void SendMessage(string msg)
{
try
{
byte[] outStream = Encrypt($"{msg}$");
NetworkStream serverStream = clientSocket.GetStream();
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
byte[] inStream = new byte[clientSocket.ReceiveBufferSize];
serverStream.Read(inStream, 0, (int)clientSocket.ReceiveBufferSize);
string returnData = Decrypt(inStream);
AppendClientMessage(returnData);
richTextBox2.Text = "";
richTextBox2.Focus();
}
catch (Exception e)
{
AppendClientMessage($" >> Client Error: {e.Message}");
}
}
private void button1_Click(object sender, EventArgs ev)
{
try
{
SendMessage(richTextBox2.Text);
}
catch (Exception e)
{
AppendClientMessage($" >> Client Error: {e.Message}");
}
}
static byte[] Encrypt(string stringToEncrypt)
{
byte[] encryptedBytes;
using (Aes AES = Aes.Create())
{
AES.Key = salt;
AES.IV = IV;
AES.Mode = CipherMode.CBC;
AES.Padding = PaddingMode.PKCS7;
var encryptor = AES.CreateEncryptor(AES.Key, AES.IV);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter sw = new StreamWriter(cs))
{
sw.Write(stringToEncrypt);
}
encryptedBytes = ms.ToArray();
if (!cs.HasFlushedFinalBlock)
cs.FlushFinalBlock();
}
}
}
var combined = new byte[IV.Length + encryptedBytes.Length];
Array.Copy(IV, 0, combined, 0, IV.Length);
Array.Copy(encryptedBytes, 0, combined, IV.Length, encryptedBytes.Length);
return combined;
}
static string Decrypt(byte[] bytesToDecrypt)
{
string decryptedString = null;
using (Aes AES = Aes.Create())
{
AES.Key = salt;
byte[] cipherText = new byte[bytesToDecrypt.Length - IV.Length];
Array.Copy(bytesToDecrypt, IV, IV.Length);
Array.Copy(bytesToDecrypt, IV.Length, cipherText, 0, cipherText.Length);
AES.IV = IV;
AES.Mode = CipherMode.CBC;
AES.Padding = PaddingMode.PKCS7;
var decryptor = AES.CreateDecryptor(AES.Key, AES.IV);
using (MemoryStream ms = new MemoryStream(cipherText))
{
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
using (StreamReader sr = new StreamReader(cs))
{
decryptedString = sr.ReadToEnd();
}
}
}
}
return decryptedString;
}
}
}
. 패딩 모드 변경 및/또는 Base64 로의 변환을 포함합니다. 최종 결과는 항상 인코딩이 엉망이되어 일련의 임의의 문자가 튀어 나오거나 "패딩이 유효하지 않으므로 제거 할 수 없습니다."라는 메시지가 나타납니다. 암호를 해독 할 때 오류가 발생합니다 (클라이언트 측).
도움이 될 것입니다.
감사합니다.
확인이 : https://stackoverflow.com/questions/8583112/padding-is-invalid-and-can not-will-removed-will-do- 제거 할 수 없음 – Sunil
'networkStream.Read (bytesFrom, 0, (int) client.ReceiveBufferSize);'- 귀하의 probl이 아닐 수도 있습니다 하지만이 함수의 반환 값을 무시해서는 안됩니다. 요청한 바이트 수보다 적을 수 있습니다. –
@DylanNicholson 필자는 암호화 된 값이 항상 64 바이트이므로 64 바이트로 하드 코딩하는 것으로 되돌 렸습니다. 클라이언트 측에서이 문제를 해결했지만 지금은 서버 측에서 문제가 발생했습니다. 문제는 다음과 같은 결과 일 수 있다고 생각합니다. 'byte [] cipherText = new byte [bytesToDecrypt.Length - IV.Length]; Array.Copy (bytesToDecrypt, IV, IV.Length); 배열의 길이를 64 바이트에서 48 바이트로 변경하기 때문에 (Init Vector가 16 바이트 길이입니다) –