如何正确初始化javax.crypto.Cipher?
我正在尝试编写一个基于套接字的、非集中式的加密消息传递程序。不幸的是,我对密码有很多问题。我的客户代码如下:如何正确初始化javax.crypto.Cipher?,java,cryptography,Java,Cryptography,我正在尝试编写一个基于套接字的、非集中式的加密消息传递程序。不幸的是,我对密码有很多问题。我的客户代码如下: import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.net.Socket; import java.net.U
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
public class Client {
Socket socket;
Cipher decrypt;
Cipher encrypt;
InputStream is;
OutputStream os;
public String read() {
try {
byte[] by = new byte[is.available()];
System.out.println(by.length);
if (by.length == 0) {
return null;
}
is.read(by);
return new String(decrypt.doFinal(by));
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public void write(String str) {
System.out.println("writing");
try {
os.write(encrypt.doFinal(str.getBytes()));
} catch (IOException e) {
e.printStackTrace();
return;
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Client(String ip, int port) {
try {
socket = new Socket(ip, port);
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(Main.KEY_ENCRYPTION);
keyPairGen.initialize(Main.SIZE);
KeyPair pair = keyPairGen.generateKeyPair();
decrypt = Cipher.getInstance(Main.CIPHER_ENCRYPTION);
decrypt.init(Cipher.DECRYPT_MODE, pair.getPrivate());
ObjectOutputStream coos = new ObjectOutputStream(socket.getOutputStream());
System.out.println("1: client");
coos.writeObject(pair.getPublic());
System.out.println("2");
ObjectInputStream cois = new ObjectInputStream(socket.getInputStream());
System.out.println("3");
while(cois.available() > 2048) {}
System.out.println("4");
PublicKey pk = (PublicKey)cois.readObject();
System.out.println("5");
encrypt = Cipher.getInstance(Main.CIPHER_ENCRYPTION);// RSA/ECB/PKCS1Padding
encrypt.init(Cipher.ENCRYPT_MODE, pk);
is = socket.getInputStream();
os = socket.getOutputStream();
} catch (NumberFormatException e1) {
e1.printStackTrace();
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
} catch (NoSuchPaddingException e1) {
e1.printStackTrace();
} catch (InvalidKeyException e1) {
e1.printStackTrace();
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
}
}
我的服务器代码是:
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
public class Server {
Socket socket;
ServerSocket sersock;
Cipher decrypt;
Cipher encrypt;
InputStream is;
OutputStream os;
public String read() {
try {
byte[] by = new byte[is.available()];
System.out.println(by.length);
if (by.length == 0) {
return null;
}
is.read();
return new String(decrypt.doFinal(by));
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public void write(String str) {
System.out.println("writing");
try {
os.write(encrypt.doFinal(str.getBytes()));
} catch (IOException e) {
e.printStackTrace();
return;
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Server(int port) {
try {
sersock = new ServerSocket(port);
socket = sersock.accept();
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(Main.KEY_ENCRYPTION);
keyPairGen.initialize(Main.SIZE);
KeyPair pair = keyPairGen.generateKeyPair();
decrypt = Cipher.getInstance(Main.CIPHER_ENCRYPTION);
decrypt.init(Cipher.DECRYPT_MODE, pair.getPrivate());
ObjectInputStream cois = new ObjectInputStream(socket.getInputStream());
System.out.println("1: server");
while (cois.available() > 2047) {}
System.out.println("2");
PublicKey pk = (PublicKey)cois.readObject();
System.out.println("3");
encrypt = Cipher.getInstance(Main.CIPHER_ENCRYPTION);
encrypt.init(Cipher.ENCRYPT_MODE, pk);
new ObjectOutputStream(socket.getOutputStream()).writeObject(pair.getPublic());
os = socket.getOutputStream();
System.out.println("4");
System.out.println("5");
is = socket.getInputStream();
System.out.println("6");
} catch (NumberFormatException e1) {
e1.printStackTrace();
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
} catch (NoSuchPaddingException e1) {
e1.printStackTrace();
} catch (InvalidKeyException e1) {
e1.printStackTrace();
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
}
}
Main.KEY\u加密、Main.CIPHER\u加密和Main.SIZE都会影响错误。例如:“RSA”、“RSA”和1028给了我:
javax.crypto.BadPaddingException: Decryption error
at java.base/sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:378)
at java.base/sun.security.rsa.RSAPadding.unpad(RSAPadding.java:290)
at java.base/com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:366)
at java.base/com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:392)
at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2202)
at comm.Server.read(Server.java:37)
java.security.NoSuchAlgorithmException: Cannot find any provider supporting DSA
(后面还有更多内容,但这只是通过JFrame调用代码的方式)
出于某种原因,“RSA”、“RSA”、2048(仅适用于某些消息大小,如“hello?”)打印:
“DSA”、“DSA”(任何数字)给了我:
javax.crypto.BadPaddingException: Decryption error
at java.base/sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:378)
at java.base/sun.security.rsa.RSAPadding.unpad(RSAPadding.java:290)
at java.base/com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:366)
at java.base/com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:392)
at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2202)
at comm.Server.read(Server.java:37)
java.security.NoSuchAlgorithmException: Cannot find any provider supporting DSA
其他人也给了我类似的例外
我主要是要离开这里
供参考。
我的问题是:我需要什么Main.KEY_加密(String)、Main.CIPHER_加密(String)和Main.SIZE(int)值来实现这一点,还是需要更改客户端或服务器类中的某些内容
提前
如果您想用RSA加密/解密,那么在密钥生成过程中需要“RSA”而不是“DSA”。你也可以发布你的
Main
值吗?你似乎需要交通安全。看在皮特的份上,请使用TLS。目前你看不到自己在做什么,反复试验也不会有结果;如果你让它运行,你就不能保证它的安全。TLS已经够难了。目前,字段错误,编码错误,加密错误,异常处理错误,调试的方式错误,并且您使用的是试错安全性,这是行不通的。学习传输安全/加密,并了解如何处理异常。例如,使用GeneralSecurityException
,不打印堆栈跟踪。相反,抛出一个RuntimeException
-这样你会得到一个堆栈跟踪,因为你的问题会中断-这是需要的。@MaartenBodewes好的,谢谢你的反馈。然而,你真的有什么有用的建议吗?我理解代码是错误的,这就是我问这个问题的原因。我需要的是一个关于下一步做什么的真正建议,比如一个关于如何做的教程的链接?(基本上,你的第二个评论毫无用处。它告诉我没有什么建设性的东西,不像你的第一个评论,它给了我一个真正的建议。)那是因为我不知道从哪里开始。如果您要设计一个传输安全协议,您不应该从零开始,您应该研究其他协议,否则您创建的任何解决方案都不会是安全的。学习课堂设计、流式编程(例如,尝试使用资源)、干净的编程技术。