JavaAES加密在单元测试中工作。但从UDP/TCP传入时失败
我的代码 运行时,等待udp数据包到来时,我会收到此消息JavaAES加密在单元测试中工作。但从UDP/TCP传入时失败,java,encryption,Java,Encryption,我的代码 运行时,等待udp数据包到来时,我会收到此消息 Plain Text : 6 75 3 Encrypted Text : 74 43 117 Decrypted Text : 6 75 3 TestServer使用 javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher at com.sun.crypto.
Plain Text : 6 75 3
Encrypted Text : 74 43 117
Decrypted Text : 6 75 3
TestServer使用
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..)
at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
好的,这是一个可怕的例子,我将在以后更新,我将不得不睡觉 请注意,对于正常数据,使用ECB编码总是不安全的。当有可能发生中间人攻击(填充Oracle攻击)时,CBC编码非常不安全。但它应该起作用。如果您有更新的Java 7,请尝试使用
“AES/GCM/NoPadding”
,并且不要忘记将随机IV发送到另一端
private static void udpServer()
{
try
{ //This is whats coming in ==> byte[] password={6,75,3};
DatagramSocket serverSocket = new DatagramSocket(18000);
byte[] receiveData = new byte[64];
while (true)
{
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
byte[] b = decrpytBytes(receivePacket.getData());
}
}
catch(Exception e)
{
//blahh
}
}
好的,这是一个可怕的例子,我将在以后更新,我将不得不睡觉 请注意,对于正常数据,使用ECB编码总是不安全的。当有可能发生中间人攻击(填充Oracle攻击)时,CBC编码非常不安全。但它应该起作用。如果您有更新的Java 7,请尝试使用
“AES/GCM/NoPadding”
,并且不要忘记将随机IV发送到另一端
private static void udpServer()
{
try
{ //This is whats coming in ==> byte[] password={6,75,3};
DatagramSocket serverSocket = new DatagramSocket(18000);
byte[] receiveData = new byte[64];
while (true)
{
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
byte[] b = decrpytBytes(receivePacket.getData());
}
}
catch(Exception e)
{
//blahh
}
}
希望这些线程对您有所帮助:如果您以二进制格式传输数据,为什么要将数据转换为base64?从
getData()
?@Mrshll187的字节数组长度是多少?@Mrshll187:我怀疑问题实际上是您只是使用getData()
,而没有调用getLength()
,但是base64使事情更加混乱。除此之外,如果您需要base64,您不应该使用sun.misc
,而应该使用Apache编解码器库。就我个人而言,我不喜欢输出字节数组的Base64编码器,顺便说一下,整个想法是Base64是文本,而不是二进制。想象一下,当您将base 64编码的二进制文件插入到与ASCII不兼容的内容中时会有多有趣(但如果这超出了您的想象,请首先从UDP数据包中取出base 64)。希望这些线程对您有所帮助:您为什么要将数据转换为base 64,如果您是以二进制格式传输它,那么getData()
的字节数组的长度是多少?@Mrshll187:我怀疑问题实际上是您只是在使用getData()
而没有调用getLength()
,但是base64会让事情更加混乱。此外,您不应该使用sun.misc
,如果需要base 64,请使用Apache编解码器库。就我个人而言,我不喜欢输出字节数组的Base64编码器,顺便说一下,整个想法是Base64是文本,而不是二进制。想象一下,当您将base64编码的二进制文件插入到与ASCII不兼容的内容中时会有多有趣(但如果这超出了您的想象,请首先从UDP数据包中删除base64)。谢谢,我感谢您的回复。这似乎奏效了。我不太喜欢IvParameterSpec到底在做什么,虽然如果你用同一个密钥加密多条消息,你总是需要一个IV。对于大多数密码模式,IV应该是随机化的,并且大部分时间是在密文之前。ECB不使用V,但加密文本时不安全。谢谢。我感谢您的回复。这似乎奏效了。我不太喜欢IvParameterSpec到底在做什么,虽然如果你用同一个密钥加密多条消息,你总是需要一个IV。对于大多数密码模式,IV应该是随机化的,并且大部分时间是在密文之前。ECB不使用V,但加密(如文本)不安全。
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.nio.charset.Charset;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class UDP_AES {
/**
* @param args
* @throws SocketException
*/
public static void main(String[] args) throws SocketException {
Thread t = new Thread(new Runnable() {
DatagramSocket socket;
byte[] receiveData = new byte[1024];
Cipher aesCipher;
{
try {
socket = new DatagramSocket(18000);
aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec zeroIV = new IvParameterSpec(new byte[aesCipher.getBlockSize()]);
SecretKey key = new SecretKeySpec(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,}, "AES");
aesCipher.init(Cipher.DECRYPT_MODE, key, zeroIV);
} catch (Exception e) {
throw new IllegalStateException("Could not create server socket or cipher", e);
}
}
@Override
public void run() {
while (true) {
DatagramPacket packet = new DatagramPacket(receiveData, receiveData.length);
try {
socket.receive(packet);
final byte[] plaintextBinary = aesCipher.doFinal(packet.getData(), 0, packet.getLength());
String plaintext = new String(plaintextBinary, Charset.forName("UTF-8"));
System.out.println(plaintext);
} catch (Exception e) {
throw new IllegalStateException("Could not receive or decrypt packet");
}
}
}
});
t.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// yeah, whatever
}
DatagramSocket sendingSocket = new DatagramSocket();
String plaintext = "1234";
byte[] plaintextBinary = plaintext.getBytes(Charset.forName("UTF-8"));
try {
Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKey key = new SecretKeySpec(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,}, "AES");
IvParameterSpec zeroIV = new IvParameterSpec(new byte[aesCipher.getBlockSize()]);
aesCipher.init(Cipher.ENCRYPT_MODE, key, zeroIV);
final byte[] ciphertextBinary = aesCipher.doFinal(plaintextBinary);
DatagramPacket sendingPacket = new DatagramPacket(ciphertextBinary, ciphertextBinary.length);
sendingPacket.setSocketAddress(new InetSocketAddress("localhost", 18000));
sendingSocket.send(sendingPacket);
} catch (Exception e) {
throw new IllegalStateException("Could not send or encrypt", e);
}
}
}