如何正确初始化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)值来实现这一点,还是需要更改客户端或服务器类中的某些内容

提前

  • 非常感谢您花时间帮助我解决这个问题,非常感谢
  • 我知道catch块不太令人满意,这是一项仍在进行中的工作,稍后我将添加实现来解决这个问题。目前,我只是想让一些东西开始运行
  • 我还知道,我的代码中有打印行,这是在我遇到代码挂起问题时产生的,我还没有删除它们,因为我可能再次需要它们

  • 如果您想用RSA加密/解密,那么在密钥生成过程中需要“RSA”而不是“DSA”。你也可以发布你的
    Main
    值吗?你似乎需要交通安全。看在皮特的份上,请使用TLS。目前你看不到自己在做什么,反复试验也不会有结果;如果你让它运行,你就不能保证它的安全。TLS已经够难了。目前,字段错误,编码错误,加密错误,异常处理错误,调试的方式错误,并且您使用的是试错安全性,这是行不通的。学习传输安全/加密,并了解如何处理异常。例如,使用
    GeneralSecurityException
    ,不打印堆栈跟踪。相反,抛出一个
    RuntimeException
    -这样你会得到一个堆栈跟踪,因为你的问题会中断-这是需要的。@MaartenBodewes好的,谢谢你的反馈。然而,你真的有什么有用的建议吗?我理解代码是错误的,这就是我问这个问题的原因。我需要的是一个关于下一步做什么的真正建议,比如一个关于如何做的教程的链接?(基本上,你的第二个评论毫无用处。它告诉我没有什么建设性的东西,不像你的第一个评论,它给了我一个真正的建议。)那是因为我不知道从哪里开始。如果您要设计一个传输安全协议,您不应该从零开始,您应该研究其他协议,否则您创建的任何解决方案都不会是安全的。学习课堂设计、流式编程(例如,尝试使用资源)、干净的编程技术。