我有我的C#服務器和我的Java客戶端,他們的通信是加密的,但當客戶端發送加密查詢時,服務器無法解密它,它可以但它完全不可讀,它像轉換字節數組爲字符串,完全不可讀的,這是對客戶端的加密:Java加密C#解密不會工作
public byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException
{
byte[] encryptedBytes = null;
byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
final Cipher cipher = Cipher.getInstance(AES_CBC_PKCS5PADDING);
final byte[] keyData = Arrays.copyOf(passwordBytes, KEY_SIZE
/Byte.SIZE);
final byte[] ivBytes = Arrays.copyOf(keyData, cipher.getBlockSize());
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyData, "AES"),
new IvParameterSpec(ivBytes));
encryptedBytes = cipher.doFinal(bytesToBeEncrypted);
return encryptedBytes;
}
而在服務器端解密:提前
internal string DecryptText(string inputString, Key k)
{
try
{
inputString = inputString.Replace("\0", "");
byte[] decryptedBytes = null;
byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
byte[] bytesToBeDecrypted = Convert.FromBase64String(inputString);
byte[] passwordBytes = Encoding.UTF8.GetBytes("azaz");
passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
using (MemoryStream ms = new MemoryStream())
{
using (RijndaelManaged AES = new RijndaelManaged())
{
AES.KeySize = 256;
AES.BlockSize = 128;
var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize/8);
AES.IV = key.GetBytes(AES.BlockSize/8);
AES.Padding = PaddingMode.None;
AES.Mode = CipherMode.CBC;
using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
cs.Close();
}
decryptedBytes = ms.ToArray();
}
}
return Encoding.UTF8.GetString(decryptedBytes);
}
catch (Exception ex)
{
throw new SystemException(ex.Message);
}
}
感謝
編輯在Java客戶端,這個函數調用AES_ENCRYPT函數:
public String EncryptText(String input) throws NoSuchAlgorithmException
{
byte[] bytesToBeEncrypted = input.getBytes();
byte[] passwordBytes = Config.ServerKey.getBytes();
MessageDigest md = MessageDigest.getInstance("SHA-256");
passwordBytes = md.digest(passwordBytes);
byte[] bytesEncrypted = null;
try {
bytesEncrypted = AES_Encrypt(bytesToBeEncrypted, passwordBytes);
} catch (NoSuchPaddingException ex) {
Logger.getLogger(CryptoClass.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvalidAlgorithmParameterException ex) {
Logger.getLogger(CryptoClass.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvalidKeyException ex) {
Logger.getLogger(CryptoClass.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalBlockSizeException ex) {
Logger.getLogger(CryptoClass.class.getName()).log(Level.SEVERE, null, ex);
} catch (BadPaddingException ex) {
Logger.getLogger(CryptoClass.class.getName()).log(Level.SEVERE, null, ex);
}
return Base64.getEncoder().encodeToString(bytesEncrypted);
}
編輯實現基本SslStream和驗證服務器端
private void Do()
{
int requestCount = 0;
string serverResponse = null;
string rCount = null;
string dataFromClient = null;
Byte[] sendBytes = null;
requestCount = 0;
Responder.Responder R = new Responder.Responder();
while ((true))
{
try
{
byte[] buffer = new byte[4];
requestCount = requestCount + 1;
bool leaveInnerStreamOpen = true;
RemoteCertificateValidationCallback validationCallback =
new RemoteCertificateValidationCallback(ClientValidationCallback);
LocalCertificateSelectionCallback selectionCallback =
new LocalCertificateSelectionCallback(ServerCertificateSelectionCallback);
EncryptionPolicy encryptionPolicy = EncryptionPolicy.AllowNoEncryption;
_sslStream = new SslStream(clientSocket.GetStream(),
leaveInnerStreamOpen, validationCallback, selectionCallback, encryptionPolicy);
X509Certificate2 certificate = ServerCertificate.Servercertificate(); //method that has access to the embedded certificate
bool requireClientCertificate = true;
SslProtocols enabledSslProtocols = SslProtocols.Tls11 | SslProtocols.Tls12;
bool checkCertificateRevocation = true;
_sslStream.AuthenticateAsServer
(certificate, requireClientCertificate, enabledSslProtocols, checkCertificateRevocation);
buffer = new byte[4];
int readBytes = _sslStream.Read(buffer, 0, 4);
if (readBytes == 0)
break;
int MessageSize = BitConverter.ToInt32(buffer, 0);
byte[] bufferreader = new byte[MessageSize];
clientSocket.ReceiveBufferSize = MessageSize;
readBytes = _sslStream.Read(bufferreader, 0, MessageSize);
Console.WriteLine(Convert.ToString(MessageSize));
rCount = Convert.ToString(requestCount);
dataFromClient = Encoding.ASCII.GetString(bufferreader);
byte[] outbuffer = new byte[4];
serverResponse = R.Respond(dataFromClient, K, clientSocket);
sendBytes = Encoding.ASCII.GetBytes(serverResponse);
outbuffer = new byte[4];
outbuffer = BitConverter.GetBytes(sendBytes.Length);
_sslStream.Write(outbuffer, 0, 4);
_sslStream.Flush();
clientSocket.SendBufferSize = sendBytes.Length;
MessageBox.Show(serverResponse);
_sslStream.Write(sendBytes, 0, sendBytes.Length);
_sslStream.Flush();
}
catch (Exception ex)
{
EndPointHandler.RemoveEndPoint(clientSocket);
clientSocket.Close();
Console.WriteLine("User Server >> " + ex.ToString());
Thread.CurrentThread.Abort();
}
}
EndPointHandler.RemoveEndPoint(clientSocket);
Console.WriteLine("User Server >> " + "Client No:" + Convert.ToString(clNo) + " Stopped!");
}
private bool ClientValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
switch (sslPolicyErrors)
{
case SslPolicyErrors.RemoteCertificateNameMismatch:
Console.WriteLine("Client's name mismatch. End communication ...\n");
return false;
case SslPolicyErrors.RemoteCertificateNotAvailable:
Console.WriteLine("Client's certificate not available. End communication ...\n");
return false;
case SslPolicyErrors.RemoteCertificateChainErrors:
Console.WriteLine("Client's certificate validation failed. End communication ...\n");
return false;
}
Console.WriteLine("Client's authentication succeeded ...\n");
return true;
}
private X509Certificate ServerCertificateSelectionCallback(object sender, string targetHost, X509CertificateCollection localCertificates, X509Certificate remoteCertificate, string[] acceptableIssuers)
{
return ServerCertificate.Servercertificate();
}
你可以在java端解密你的數據嗎? –
@StephenReindl是的,沒問題 –
你的'passwordBytes'變量包含鍵和IV嗎?這不會導致你的問題,但你應該儘快改變。 IV應該隨機生成每個加密。 –