Demonstrieren Sie die Verwendung des öffentlichen RSA-Schlüsselsystems für den Austausch von Nachrichten, die Vertraulichkeit und Integrität / Authentifizierung gewährleisten
Ich versuche, die Verwendung des RSA-Public-Key-Systems für den Austausch von Nachrichten zu demonstrieren, die Vertraulichkeit und Integrität / Authentifizierung gewährleisten. Ich versuche, eine Nachricht auf der Clientseite zu verschlüsseln und diese Informationen zum Entschlüsseln an den Server zu senden. Das Problem, das ich habe, ist, dass mein Code nicht entschlüsselt wird. Es gibt mir den folgenden Fehler:
javax.crypto.BadPaddingException: Data must start with zero
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:308)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:255)
at com.sun.crypto.provider.RSACipher.a(DashoA13*..)
at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at PKServer.decryptMessage(PKServer.java:36)
at PKServer.main(PKServer.java:69)
Public-Key-Client-Code:
import java.io.*;
import java.net.*;
import java.security.*;
import javax.crypto.*;
public class PKClient
{
public static final int kBufferSize = 8192;
public static void main(String[] args) throws Exception
{
try {
// Generate new key
KeyPair keyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
String message = "The quick brown fox jumps over the lazy dog.";
// Compute signature
Signature instance = Signature.getInstance("SHA1withRSA");
instance.initSign(privateKey);
instance.update((message).getBytes());
byte[] signature = instance.sign();
// Compute digest
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
byte[] digest = sha1.digest((message).getBytes());
// Encrypt digest
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] encryptedMsg = cipher.doFinal(digest);
//Store the key in a file
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("KeyFile.xx"));
out.writeObject(privateKey);
out.close();
System.out.println("Client - Message: " + message);
System.out.println("Client - Encrypted: " + PKServer.asHex(encryptedMsg));
String host = "localhost";
int port = 7999;
Socket s = new Socket(host, port);
//Open stream to cipher server
DataOutputStream os = new DataOutputStream(s.getOutputStream());
os.writeInt(encryptedMsg.length);
os.write(encryptedMsg);
os.writeInt(digest.length);
os.write(digest);
os.writeInt(signature.length);
os.write(signature);
os.flush();
os.close();
//Close socket
s.close();
}catch (Exception e) {
e.printStackTrace();
}
}
}
Public-Key-Servercode:
import java.io.*;
import java.net.*;
import java.security.*;
import javax.crypto.*;
public class PKServer
{
public void decryptMessage(InputStream inStream) throws IOException, NoSuchAlgorithmException
{
try {
//Create the Data input stream from the socket
DataInputStream dis = new DataInputStream(inStream);
//Get the key
ObjectInputStream in = new ObjectInputStream(new FileInputStream("KeyFile.xx"));
//ObjectOutputStream outSocket = new ObjectOutputStream(s.getOutputStream());
PrivateKey privatekey = (PrivateKey) in.readObject();
System.out.println("Key Used: " + in.toString());
in.close();
//Initiate the cipher
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE,privatekey);
int len = dis.readInt();
byte[] encryptedMsg = new byte[len];
dis.readFully(encryptedMsg);
System.out.println("Server - Msg Length: " + len);
System.out.println("Server - Encrypted: " + asHex(encryptedMsg));
// -Print out the decrypt String to see if it matches the original message.
byte[] plainText = cipher.doFinal(encryptedMsg);
System.out.println("Decrypted Message: " + new String(plainText, "SHA"));
} catch (Exception e) {
e.printStackTrace();
}
}
//Function to make the bytes printable (hex format)
public static String asHex(byte buf[]) {
StringBuilder strbuf = new StringBuilder(buf.length * 2);
int i;
for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10) {
strbuf.append("0");
}
strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}
return strbuf.toString();
}
public static void main(String[] args) throws Exception
{
int port = 7999;
ServerSocket server = new ServerSocket(port);
Socket s = server.accept();
PKServer cs = new PKServer();
cs.decryptMessage(s.getInputStream());
server.close();
}
}
Hier ist die Ausgabe, die ich auf der Serverseite erhalte:
Key Used: java.io.ObjectInputStream@fee4648
Server - Msg Length: 128
Server - Encrypted: 8c23b2cd96c07950f4901a670b025531b5f52be0730e4548c9a76090d7ae65a8ce82901c66acfb6bd79520cf8d86bf74bf3105fd638892a681a6905556cbadf394915fbdc09babb5b78b9dd06382e92604e9ca88901613520ccb45fcc376e813df059ebc649c52f233dc2632733d99212b42ce54e59ebd6d9dca98af36a20fc6
javax.crypto.BadPaddingException: Data must start with zero
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:308)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:255)
at com.sun.crypto.provider.RSACipher.a(DashoA13*..)
at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at PKServer.decryptMessage(PKServer.java:36)
at PKServer.main(PKServer.java:69)
Mir ist aufgefallen, dass, wenn ich die Zeile anpasse:
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
zu
Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");
Das Programm entschlüsselt, aber es entschlüsselt nicht die beabsichtigte Zeichenfolge. Es sieht aus wie das:
Decrypted Message: E???.1G?:*?$??|o\?"?
V????????O)Z?j??a?!p)6??????_??T*?c?6O????????:?(??C?,??'??`??????(?2D?mC?OLc<7?'?S?R?
Bitte lassen Sie mich wissen, ob Sie sehen können, wo ich mit diesem Code falsch liege.