簡體   English   中英

JAVA SSL為服務器端的每個客戶端生成新的密鑰庫證書

[英]JAVA SSL Generate a new keystore certificate for each client on server side

我試圖使我的服務台聊天應用程序安全。 在我的客戶端上,我創建了它,以便每個客戶端都可以在運行時創建其證書和密鑰庫(因此,並非每個客戶端都具有相同的密鑰庫),並且在服務器上也完全相同。 但是,在服務器端,這發生在while循環之前,該循環接受來自客戶端的連接。 這意味着服務器為每個連接使用相同的證書,這將使惡意用戶很容易僅通過使用服務器的證書就可以將數據發送到服務器(整個服務器啟動時都是相同的)。

我可以在服務器的while循環中以某種方式創建證書和密鑰庫,並以某種方式將該證書用於新的傳入連接(sslsocket.accept)。 (順便說一句,我只能使用一個服務器端口進行所有連接)。

以下是我的客戶端實現(代碼段):

String domainName ="localhost";

KeyPairGenerator keyPairGenerator;
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider ());

keyPairGenerator = KeyPairGenerator.getInstance("RSA");

keyPairGenerator.initialize(1024);
KeyPair KPair = keyPairGenerator.generateKeyPair();

X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator(); 

v3CertGen.setSerialNumber(BigInteger.valueOf(Math.abs(new SecureRandom().nextInt())));
v3CertGen.setIssuerDN(new X509Principal("CN=" + domainName + ", OU=None, O=None L=None, C=None"));
v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30));
v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 365*10)));
v3CertGen.setSubjectDN(new X509Principal("CN=" + domainName + ", OU=None, O=None L=None, C=None"));

v3CertGen.setPublicKey(KPair.getPublic());
v3CertGen.setSignatureAlgorithm("MD5WithRSAEncryption");

X509Certificate pkCertificate = v3CertGen.generateX509Certificate(KPair.getPrivate());  

KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load(null, null);
Random rand = new Random();
String x = rand.nextInt(1000000000) + "";
char[] passCert = x.toCharArray();
keystore.setKeyEntry("user", KPair.getPrivate(), passCert, new X509Certificate[] {pkCertificate});
FileOutputStream fos;

fos = new FileOutputStream("cert.cert");
fos.write(pkCertificate.getEncoded());
fos.close();
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
Random rand2 = new Random();
String y = rand2.nextInt(1000000000) + "";
char[] password = y.toCharArray();
ks.load(null, password);
PrivateKeyEntry entry = new PrivateKeyEntry(KPair.getPrivate(),
    new java.security.cert.Certificate[]{pkCertificate});
ks.setEntry("newuser",entry , new KeyStore.PasswordProtection(password));

fos = new FileOutputStream("mySrvKeystore2");
ks.store(fos, password);
fos.close();
System.setProperty("javax.net.ssl.keyStore", "mySrvKeystore2");
System.setProperty("javax.net.ssl.keyStorePassword", y);
System.setProperty("javax.net.ssl.trustStore", "mySrvKeystore");
System.setProperty("javax.net.ssl.trustStorePassword", "harinder99");
TrustManager[] trustAllCerts = new TrustManager[] {
    new X509TrustManager() {
        public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
        }

        public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
        }

        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }
};
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, y.toCharArray());
SSLContext ctx = SSLContext.getInstance("TLSv1.2");
ctx.init(kmf.getKeyManagers(), trustAllCerts, new SecureRandom());
sslsocketfactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
sslsocket = (SSLSocket) sslsocketfactory.createSocket(server, hh);

以下是我的服務器實現(代碼段)。

String domainName ="localhost";

KeyPairGenerator keyPairGenerator;
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider ());

keyPairGenerator = KeyPairGenerator.getInstance("RSA");

keyPairGenerator.initialize(1024);
KeyPair KPair = keyPairGenerator.generateKeyPair();

X509V3CertificateGenerator v3CertGen = new X509V3CertificateGenerator(); 


v3CertGen.setSerialNumber(BigInteger.valueOf(Math.abs(new SecureRandom().nextInt())));
v3CertGen.setIssuerDN(new X509Principal("CN=" + domainName + ", OU=None, O=None L=None, C=None"));
v3CertGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30));
v3CertGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 365*10)));
v3CertGen.setSubjectDN(new X509Principal("CN=" + domainName + ", OU=None, O=None L=None, C=None"));

v3CertGen.setPublicKey(KPair.getPublic());
v3CertGen.setSignatureAlgorithm("MD5WithRSAEncryption");

X509Certificate pkCertificate = v3CertGen.generateX509Certificate(KPair.getPrivate());  

KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load(null, null);
Random rand = new Random();
String x = rand.nextInt(1000000000) + "";
char[] passCert = x.toCharArray();
keystore.setKeyEntry("user", KPair.getPrivate(), passCert, new X509Certificate[] {pkCertificate});
FileOutputStream fos;

fos = new FileOutputStream("cert.cert");
fos.write(pkCertificate.getEncoded());
fos.close();
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
Random rand2 = new Random();
String y = rand2.nextInt(1000000000) + "";
char[] password = y.toCharArray();
ks.load(null, password);
PrivateKeyEntry entry = new PrivateKeyEntry(KPair.getPrivate(),
      new java.security.cert.Certificate[]{pkCertificate});
ks.setEntry("newuser",entry , new KeyStore.PasswordProtection(password));

fos = new FileOutputStream("mySrvKeystore3");
ks.store(fos, password);
fos.close();
System.setProperty("javax.net.ssl.keyStore", "mySrvKeystore3");
System.setProperty("javax.net.ssl.keyStorePassword", y);
System.setProperty("javax.net.ssl.trustStore", "mySrvKeystore");
System.setProperty("javax.net.ssl.trustStorePassword", "harinder99");
/////
clientSocket = null;
ServerSocket serverSocket = null;
SSLServerSocket server1 = (SSLServerSocket)null;
String port = JOptionPane.showInputDialog("Enter Port: ", "1234");
try {
    //SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
    TrustManager[] trustAllCerts = new TrustManager[] {
        new X509TrustManager() {
           public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
           }

           public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
           }

           public java.security.cert.X509Certificate[] getAcceptedIssuers() {
               return null;
           }
       }
   };
   KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
   kmf.init(ks, y.toCharArray());
   SSLContext ctx = SSLContext.getInstance("TLSv1.2");
   ctx.init(kmf.getKeyManagers(), trustAllCerts, new SecureRandom());
   SSLServerSocketFactory sslserversocketfactory = ctx.getServerSocketFactory();
   server1 = (SSLServerSocket) sslserversocketfactory.createServerSocket(Integer.parseInt(port));

這意味着服務器為每個連接使用相同的證書,這將使惡意用戶很容易僅通過使用服務器的證書就可以將數據發送到服務器(整個服務器啟動時都是相同的)。

不,不會。 如果沒有服務器的私鑰,則服務器證書對於任何偽造目的都不會有用,您當然需要保持私鑰。 它與SSL無關。

您的問題是虛構的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM