Đây là bài đăng đầu tiên trong loạt bài này, trong đó tôi sẽ hướng dẫn các bạn cách tạo chứng chỉ SSL trong chương trình Java. Chứng chỉ thường được sử dụng trong giao tiếp SSL, đòi hỏi xác thực máy chủ với máy khách. Điều này nhằm mục đích giúp máy khách tin tưởng rằng máy chủ thực sự là máy chủ mà nó tuyên bố. Chứng chỉ thực sự rất quan trọng trên Internet. Tất cả các giao tiếp HTTPS trên Internet đều cần phía máy chủ trình bày chứng chỉ của họ được ký bởi các CA đáng tin cậy.
Luồng cơ bản của việc tạo yêu cầu là trước tiên chúng ta sử dụng một số công cụ để tạo yêu cầu chứng chỉ, yêu cầu chứng chỉ này sẽ được gửi đến các CA đáng tin cậy để ký, sau khi ký chứng chỉ, chứng chỉ này sẽ được gửi đến người yêu cầu. Người yêu cầu có thể cài đặt chứng chỉ trên máy chủ của họ sau đó.
Có rất nhiều thư viện bạn có thể sử dụng để hoàn thành các bước này. Ví dụ: openssl, Java keytool, iKeyman. Ngoài ra trong Java, bạn có thể tự viết mã để tạo chứng chỉ.
Nếu bạn đang sử dụng keytool, thì lệnh bên dưới có thể giúp bạn tạo khóa riêng và chứng chỉ tự ký liên quan.
keytool -genkeypair -alias rsakey -keyalg rsa -storepass passphrase -keystore mytestkeys.jks -storetype JKS -dname "CN=ROOT"
Trong bài đăng này, chúng ta sẽ trước tiên hiển thị cách dễ nhất để tạo chứng chỉ khả dụng - chứng chỉ tự ký. Chứng chỉ tự ký là chứng chỉ mà người phát hành chứng chỉ cũng là chủ thể của chứng chỉ, tức là bạn tự ký chứng chỉ của mình bằng khóa riêng của bạn.
Trong Java, có một lớp có tên là CertAndKeyGen có thể được sử dụng để tạo khóa và chứng chỉ. Tạo một cặp khóa và cung cấp quyền truy cập vào chúng. Lớp này được cung cấp chủ yếu để dễ sử dụng. Điều này cung cấp một số chức năng quản lý chứng chỉ đơn giản. Cụ thể, nó cho phép bạn tạo chứng chỉ X.509 tự ký cũng như yêu cầu ký chứng chỉ dựa trên PKCS 10.
Dưới đây là đoạn mã để tạo chứng chỉ tự ký:
import java.security.cert.X509Certificate;
import sun.security.tools.keytool.CertAndKeyGen;
import sun.security.x509.X500Name;
public class SelfSignedCertificateGeneration {
public static void main(String[] args){
try{
CertAndKeyGen keyGen=new CertAndKeyGen("RSA","SHA1WithRSA",null);
keyGen.generate(1024);
//Generate self signed certificate
X509Certificate[] chain=new X509Certificate[1];
chain[0]=keyGen.getSelfCertificate(new X500Name("CN=ROOT"), (long)365*24*3600);
System.out.println("Certificate : "+chain[0].toString());
}catch(Exception ex){
ex.printStackTrace();
}
}
}
Hãy xem dữ liệu chứng chỉ là gì:
Certificate : [
[
Version: V3
Subject: CN=ROOT
Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5
Key: Sun RSA public key, 1024 bits
modulus: 114391309107542773913020327258312183039826043488144930936432429784366769808118582358673188617553493179715429490538390339548553158770231498533107085203543482991384318715251748594629731873902297622858400215317090155179482056595085606008433735465924998820797111761561551868239613864908732016915661242341876829949
public exponent: 65537
Validity: [From: Wed Jul 30 21:06:29 SGT 2014,
To: Thu Jul 30 21:06:29 SGT 2015]
Issuer: CN=ROOT
SerialNumber: [ 0b000b59]
]
Algorithm: [SHA1withRSA]
Signature:
0000: 94 F9 DD 3D 95 4F BC 63 A6 A3 09 9E 63 EF CA 91 ...=.O.c....c...
0010: 97 55 C1 9E B2 12 52 13 7A 7B 73 B1 B8 ED A8 EF .U....R.z.s.....
0020: F5 1C EB 27 71 F2 60 22 BC E9 0B 01 1D 70 C1 5E ...'q.`".....p.^
0030: D6 D1 E8 AB 4D 2C CC F6 70 2B 7A D4 37 95 7A CC ....M,..p+z.7.z.
0040: E2 A1 FE F9 3F 11 18 FD 36 CB 22 62 FB 5A E2 5D ....?...6."b.Z.]
0050: E6 6C BF 61 C7 1F 03 BA FE B5 85 47 DD 7F C0 CB .l.a.......G....
0060: F3 F1 A0 79 35 0F 2A F7 79 0E 1E 79 A1 11 2E 44 ...y5.*.y..y...D
0070: 85 10 F2 B3 9F 07 F0 24 D3 1A AC 28 0C CE 4B 04 .......$...(..K.
]
Từ dữ liệu chứng chỉ, bạn có thể thấy rằng Chủ thể và Người phát hành là giống nhau.
Trong bài đăng tiếp theo, tôi sẽ hướng dẫn các bạn cách tạo chuỗi chứng chỉ bằng cách lập trình Java.
Great start for developers who are working in security field
While running outside eclipse i am getting following error
SelfSignedCertificateGeneration.java:3: error: package sun.security.tools.keytoo
l does not exist
import sun.security.tools.keytool.CertAndKeyGen;
^
SelfSignedCertificateGeneration.java:4: warning: X500Name is internal proprietar
y API and may be removed in a future release
import sun.security.x509.X500Name;
^
SelfSignedCertificateGeneration.java:9: error: cannot find symbol
CertAndKeyGen keyGen=new CertAndKeyGen("RSA","SHA1WithRSA",null);
^
symbol: class CertAndKeyGen
location: class SelfSignedCertificateGeneration
SelfSignedCertificateGeneration.java:9: error: cannot find symbol
CertAndKeyGen keyGen=new CertAndKeyGen("RSA","SHA1WithRSA",null);
^
symbol: class CertAndKeyGen
location: class SelfSignedCertificateGeneration
SelfSignedCertificateGeneration.java:14: warning: X500Name is internal proprieta
ry API and may be removed in a future release
chain[0]=keyGen.getSelfCertificate(new X500Name("CN=ROOT"), (long)36
5*24*3600);
^
3 errors
2 warnings
D:\JAVA Learning\Program\Rohit>java -version
java version "1.8.0_40"
Java(TM) SE Runtime Environment (build 1.8.0_40-b26)
Java HotSpot(TM) Client VM (build 25.40-b25, mixed mode, sharing)
In latest Java 8, there are some changes with respect to the source code structure. Now you need to use below command to compile the source code to remove the errors ad warnings:
javac -XDignore.symbol.file SelfSignedCertificateGeneration.java
When javac is compiling code it doesn't link against
rt.jarby default in latest Java 8. Instead it uses special symbol filelib/ct.symwith class stubs. The option -XDignore.symbol.file is to ignore the symbol file so that it will link against rt.jar.For this change, please refer to JDK JEP 201 : Modular Source Code.
Thanks for your reply. And its working you saved me
One question how to compile with maven
Put below into your pom.xml and then mvn -X clean compile.
Note prior to maven-compiler-plugin 3.1, you should use <compilerArgument>-XDignore.symbol.file</compilerArgument> instead.
This is not working facing the same errors
C:\Users\z018653>javac -XDignore.symbol.file SelfSignedCertificateGeneration.java
d:\SelfSignedCertificate
Generation.java:5: error: package sun.security.tools.keytool does not exist
import sun.security.tools.keytool.CertAndKeyGen;
^
d:\SelfSignedCertificate
Generation.java:11: error: cannot find symbol
CertAndKeyGen keyGen=new CertAndKeyGen("RSA","SHA1WithRSA",null);
^
symbol: class CertAndKeyGen
location: class SelfSignedCertificateGeneration
d:\SelfSignedCertificate
Generation.java:11: error: cannot find symbol
CertAndKeyGen keyGen=new CertAndKeyGen("RSA","SHA1WithRSA",null);
^
symbol: class CertAndKeyGen
location: class SelfSignedCertificateGeneration
3 errors
Can you post your Java version?
I tried with Java 1.7, 1.6 and also with 1.8
I just tried on my machine with Java 8 and it works. See below:
Can you try this version?
Thank you very much
This shouldn't be that easy
I am using a server - client architecture, server has self signed certificate, through the eclipse i am calling REST API to the server but i am getting the error
Exception: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names present
can you please help me.
Well, Subject Alternative Names(SAN) allow you to specify a list of host names to be protected by a single SSL certificate. It's an X509 certificate extension. So you need to add an SAN extension in your generated certificate.
If you are in a development environment where you are doing some testing, you can implement below workaround in your code:
static { HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { // ip address of the service URL if (hostname.equals("<ip_address>")) return true; return false; } }); }This will add a default hostname verifier which you can determine which host to trust here.
Hi,
How can I compute the size of the Self Signed Certificate Generation.
Thanks
Size? Can you be more specific?
Hello;
I will begin by thanking you for answering me. Concerning my question I would like to know how to get the size (in bit or byte) of the entire self signed certificate. I mean the following certificate:
importjava.security.cert.X509Certificate;importsun.security.tools.keytool.CertAndKeyGen;importsun.security.x509.X500Name;publicclassSelfSignedCertificateGeneration {publicstaticvoidmain(String[] args){try{CertAndKeyGen keyGen=newCertAndKeyGen("RSA","SHA1WithRSA",null);keyGen.generate(1024);//Generate self signed certificateX509Certificate[] chain=newX509Certificate[1];chain[0]=keyGen.getSelfCertificate(newX500Name("CN=ROOT"), (long)365*24*3600);System.out.println("Certificate : "+chain[0].toString());}catchU just need to get its encoded data in byte array representive and get its size or save the encoded data into a certificate file and then should be using File logic to get its size.
Can anyone please provide complete code to sign a csr (which I have received from a client) and generate certificate for the client.
It's really urgent..please consider.
Where can we find the keypair which is generated here?...where is it stored after generation??
You can refer to https://www.pixelstech.net/article/1408524957-Generate-certificate-in-Java----Store-certificate-in-KeyStore on how to store