初学certificate 博客分类: secure javacertificate证书keytoolX509Certificate
程序员文章站
2024-02-28 21:10:28
...
出道半年多,感觉java要学习好多东西,可是又不知道从何入手? 工作的任务仅仅是维护项目,也仅学到些表面东西,干脆自己研究,把学到的表面东西更加深究。又后来发现如果不结合项目,很容易忘记,所以决定把自己的学习一步步写下来,初次学习,肯定有很多错误和不足的地方,希望大家多多指导。
首先接触证书,直面理解它的作用就是身份验证。但不知道它又是如何实现,它是个什么东西?于是在网上翻查资料,于是理解到一些,如下:
第一个需要理解的概念,密钥对:公钥和私钥
密钥对是一起产生的,可以互相加密解密。对于证书来说,私钥由自己保存,用于签名消息。公钥发给你想通信的人,用于验证信息是你发过来的,并且没有修改。一般只是用私钥进行签名,大家仍可以看到明文信息,作用只是确定完整性和可靠性
例如:
String str = 123456;
用私钥对str进行签名,会产生一串加密的信息。
然后把明文和密文都发过去,对方用公钥进行验证这串信息是否被修改和确定是你发过来的,后面会有代码提到,具体如何验证的就需要进一步研究了。
接下来就是证书,那证书为什么会起作用了?那就要看证书包含什么内容,一般我们所要用到的证书,我简称公钥证书,我了大致分为2部分。一部分是证书的相关信息,后面创建证书时会介绍到,第二部分就是公钥信息。此时就明白了,证书为什么会起作用,因为包含公钥。对方用私钥签名发送消息给你,而你获得对方的证书,里面有公钥,就可以进行验证了。
接下又接触到CA的一些信息,CA:certificate Authority。不明白为什么要用到CA,CA到底要干什么了?
举个例子就明白了
A要发信息给B,A用私钥签名了消息发给B,B要验证消息是A发过来的,并且没有被修改过,就必须获得A的公钥去验证,此时B可以要求A通过某种途径把公钥发过来(以证书的形式)。
这时问题来了,任何人都可以产生密钥对,B怎么知道获得的公钥是A的了。所以B就需要打电话跟A验证证书的指纹是否匹配,如果匹配就确定是A的公钥,指纹是创建证书时生成的,而且是唯一的,你可以用工具查看,后面会介绍到。大家会发现获得公钥每次都要与对方去验证,这是一个很麻烦的步骤,CA的作用就出现了,证书到CA那里走一趟,然后你获得证书就不需要在去验证了,但前提是你必须获得CA的证书,CA的证书获得就简单些,去官网弄,或者什么,但也需要验证证书的指纹,但毕竟只弄一次。
那么CA对证书做了哪些操作了?简单的来说就是签名,后面在代码会看到的。CA会有一个根证书,也就是一个自签名的证书,一般创建的证书都是自签名证书。然后CA用根证书的私钥去签名你的证书,这时你的证书就有合法性,别人只需要用CA的公钥去验证你的证书就可以了,不需要再验证了。后面代码里面会提到CA做了什么。
最后是密钥库,密钥库就是存放你的密钥一些信息,密钥库是以条目形式存放,条目英文名alias。在java代码中有个类KeyStore,查看API也可以了解密钥库。KeyStore里面存放3个实体,PrivateKeyEntry,SecretKeyEntry,TrustedCertificateEntry。一个条目就是条目名+实体。使用工具创建证书,实体是PrivateKeyEntry,其中包括私钥,和证书链,证书链第一个就是包含公钥的证书。你导入的CA公钥证书属于TrustedCertificateEntry。
其中提到了证书链,证书链包含了一串证书,首先创建时就只包含一个自签名证书,在多数情况下,倒数第一个就是你的证书,倒数第二个就是证明你的证书,倒数第三个就是证明第二个的,以此类推。我是这样理解的,不知道顺序弄错没,证书一般都是以证书链形式传递。
首现创建证书:使用KeyTool和java程序
一 KeyTool创建证书
生成本地数字证书
command:KeyTool -genkey -alias aliasName -keyStore storeName -Keyalg RSA -keysize 1024 -validity 3650 -dname "CN=country,ST=state,L=Locality,OU=OrganizationUnit,O=Organization"
genkey会产生密钥对, alias条目名称,密钥库以条目的形式存放,keystore密钥库的名称,keyalg密钥算法,keysize密钥长度,密钥有1024和2048两个长度,dname证书的相关信息。创建成功后你可以在相应的目录下找到storeName这个文件,你可以用命令查看你所创建的证书。
查看证书
command:keytool -list -keystore storename
可以看到认证指纹
导出证书
command:keytool -exportcert -alias aliasname -keystore storename -file cert.cer
你可以在相应目录下找到cert.cer文件
二 Java创建证书
生成密钥对
创建X509证书
这就创建了一个证书,大家可以从代码里面看到证书需要设置的信息,我解释一下
Version:证书版本号
SerialNumber:序列号
algorithm_Id:签名算法
subject:主体名
key:公钥
issuer:签发者
我开始提到一般证书分二部分,这是我自己分的。Key作为一部分,其它的就是证书相关信息了。大家也在代码里面看到,signer创建时,使用的也是主体的信息X500Name,后面签名的时候也是用自己的privatekey签名,所以生成的证书就是自签名证书。CA如果要做操作,CA提取出自己的X500Name信息和PrivateKey,对这二项做操作,就变成了CA签名的证书了。
证书创建完毕后,接下就是证书的功能签名了。
签名
验证
这就是我前面所提到的例子,这里用java代码实现。应用到实际中,给本机弄一个唯一标识然后签名,写在http头部,然后发给对方,对方从头部获取然后验证。当然表中已经存在你的唯一标识和证书,应该是第一次发起通信时,CA公钥证书验证你的证书,然后保存你的唯一标识和证书。
了解了证书之后,该是怎么应用了。
证书存放:
存放在表中:主要保存2个信息,证书和私钥。证书可以以X509Certificate这个类封装。
存放在keystore中。
读取证书信息:
从表中就自己写SQL。
从KeyStore中:
有了证书之后,就需要把证书发给CA了。我们就需要发给CA一个证书签名请求,简称CSR(certificate signed request),签完名后返回证书签名响应,然后导入。
生成CSR证书签名请求
用KeyTool:
command: keytool -certreq -v -alias aliasName -keystore storeName -file codesigncsr.p10
证书签名请求使用的是PKCS#10格式存放的
CA签过名之后,导入签名的证书
用KeyStore:
command:keytool -import -file cer.cer -keystore storeName
注意的是,我导入的是证书,不是证书签名响应。步骤我猜是一样的,但没实际应用过。
这是我从接触证书,然后自己查资料了解证书的一个过程,一个很简单的了解,写的很繁琐,可能也有很多理解错误的地方,希望大家多多指导。
这是我主要借鉴证书资料的一些地址,他们写的很详细。有的介绍KeyTool使用很详细,有介绍加密解密的,可以从那里学习到SSLSocket,和对称,非对称加密解密,也算是证书的应用吧。本来想写到自己里面,可是发现基本照抄的,还是列出地址给大家。
[url]
http://shellyli.iteye.com/blog/801638
http://lei-1021.iteye.com/blog/681691
http://lengjing.iteye.com/blog/1258892
http://chrui.iteye.com/blog/1018800
[/url]
解压123456
首先接触证书,直面理解它的作用就是身份验证。但不知道它又是如何实现,它是个什么东西?于是在网上翻查资料,于是理解到一些,如下:
第一个需要理解的概念,密钥对:公钥和私钥
密钥对是一起产生的,可以互相加密解密。对于证书来说,私钥由自己保存,用于签名消息。公钥发给你想通信的人,用于验证信息是你发过来的,并且没有修改。一般只是用私钥进行签名,大家仍可以看到明文信息,作用只是确定完整性和可靠性
例如:
String str = 123456;
用私钥对str进行签名,会产生一串加密的信息。
然后把明文和密文都发过去,对方用公钥进行验证这串信息是否被修改和确定是你发过来的,后面会有代码提到,具体如何验证的就需要进一步研究了。
接下来就是证书,那证书为什么会起作用了?那就要看证书包含什么内容,一般我们所要用到的证书,我简称公钥证书,我了大致分为2部分。一部分是证书的相关信息,后面创建证书时会介绍到,第二部分就是公钥信息。此时就明白了,证书为什么会起作用,因为包含公钥。对方用私钥签名发送消息给你,而你获得对方的证书,里面有公钥,就可以进行验证了。
接下又接触到CA的一些信息,CA:certificate Authority。不明白为什么要用到CA,CA到底要干什么了?
举个例子就明白了
A要发信息给B,A用私钥签名了消息发给B,B要验证消息是A发过来的,并且没有被修改过,就必须获得A的公钥去验证,此时B可以要求A通过某种途径把公钥发过来(以证书的形式)。
这时问题来了,任何人都可以产生密钥对,B怎么知道获得的公钥是A的了。所以B就需要打电话跟A验证证书的指纹是否匹配,如果匹配就确定是A的公钥,指纹是创建证书时生成的,而且是唯一的,你可以用工具查看,后面会介绍到。大家会发现获得公钥每次都要与对方去验证,这是一个很麻烦的步骤,CA的作用就出现了,证书到CA那里走一趟,然后你获得证书就不需要在去验证了,但前提是你必须获得CA的证书,CA的证书获得就简单些,去官网弄,或者什么,但也需要验证证书的指纹,但毕竟只弄一次。
那么CA对证书做了哪些操作了?简单的来说就是签名,后面在代码会看到的。CA会有一个根证书,也就是一个自签名的证书,一般创建的证书都是自签名证书。然后CA用根证书的私钥去签名你的证书,这时你的证书就有合法性,别人只需要用CA的公钥去验证你的证书就可以了,不需要再验证了。后面代码里面会提到CA做了什么。
最后是密钥库,密钥库就是存放你的密钥一些信息,密钥库是以条目形式存放,条目英文名alias。在java代码中有个类KeyStore,查看API也可以了解密钥库。KeyStore里面存放3个实体,PrivateKeyEntry,SecretKeyEntry,TrustedCertificateEntry。一个条目就是条目名+实体。使用工具创建证书,实体是PrivateKeyEntry,其中包括私钥,和证书链,证书链第一个就是包含公钥的证书。你导入的CA公钥证书属于TrustedCertificateEntry。
其中提到了证书链,证书链包含了一串证书,首先创建时就只包含一个自签名证书,在多数情况下,倒数第一个就是你的证书,倒数第二个就是证明你的证书,倒数第三个就是证明第二个的,以此类推。我是这样理解的,不知道顺序弄错没,证书一般都是以证书链形式传递。
首现创建证书:使用KeyTool和java程序
一 KeyTool创建证书
生成本地数字证书
command:KeyTool -genkey -alias aliasName -keyStore storeName -Keyalg RSA -keysize 1024 -validity 3650 -dname "CN=country,ST=state,L=Locality,OU=OrganizationUnit,O=Organization"
genkey会产生密钥对, alias条目名称,密钥库以条目的形式存放,keystore密钥库的名称,keyalg密钥算法,keysize密钥长度,密钥有1024和2048两个长度,dname证书的相关信息。创建成功后你可以在相应的目录下找到storeName这个文件,你可以用命令查看你所创建的证书。
查看证书
command:keytool -list -keystore storename
可以看到认证指纹
导出证书
command:keytool -exportcert -alias aliasname -keystore storename -file cert.cer
你可以在相应目录下找到cert.cer文件
二 Java创建证书
生成密钥对
KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA"); kg.initialize(1024, new SecureRandom()); KeyPair keyPair = kg.generateKeyPair();
创建X509证书
String name = "CN=country,ST=state,L=Locality,OU=OrganizationUnit,O=Organization"; X509CertInfo x509CertInfo = new X509CertInfo(); x509CertInfo.set(X509CertInfo.VERSION, new CertificateVersion(1)); x509CertInfo.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber((int) (System.currentTimeMillis() / 1000L))); X500Name x500Name = new X500Name(name); Signature signature = Signature.getInstance("MD5WithRSA"); X500Signer signer = new X500Signer(signature, x500Name); AlgorithmId algorithmId = signer.getAlgorithmId(); x509CertInfo.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algorithmId)); x509CertInfo.set(X509CertInfo.SUBJECT, new CertificateSubjectName(x500Name)); x509CertInfo.set(X509CertInfo.KEY, new CertificateX509Key(keyPair.getPublic())); CertificateValidity interval = new CertificateValidity(new Date(), new Date(System.currentTimeMillis() + 365000000000L)); x509CertInfo.set(X509CertInfo.VALIDITY, interval); x509CertInfo.set(X509CertInfo.ISSUER, new CertificateIssuerName(signer.getSigner())); X509CertImpl x509CertImpl = new X509CertImpl(x509CertInfo); x509CertImpl.sign(keyPair.getPrivate(), "MD5WithRSA");
这就创建了一个证书,大家可以从代码里面看到证书需要设置的信息,我解释一下
Version:证书版本号
SerialNumber:序列号
algorithm_Id:签名算法
subject:主体名
key:公钥
issuer:签发者
我开始提到一般证书分二部分,这是我自己分的。Key作为一部分,其它的就是证书相关信息了。大家也在代码里面看到,signer创建时,使用的也是主体的信息X500Name,后面签名的时候也是用自己的privatekey签名,所以生成的证书就是自签名证书。CA如果要做操作,CA提取出自己的X500Name信息和PrivateKey,对这二项做操作,就变成了CA签名的证书了。
证书创建完毕后,接下就是证书的功能签名了。
签名
String str = "123456"; Signature sig = Signature.getInstance("MD5WithRSA"); sig.initSign(privateKey); sig.update(str.getBytes()); byte[] bytes = sig.sign();
验证
String str = "123456"; Signature sig = Signature.getInstance("MD5WithRSA"); sig.initVerify(publicKey); sig.update(str.getBytes()); boolean flag = sig.verify(bytes);
这就是我前面所提到的例子,这里用java代码实现。应用到实际中,给本机弄一个唯一标识然后签名,写在http头部,然后发给对方,对方从头部获取然后验证。当然表中已经存在你的唯一标识和证书,应该是第一次发起通信时,CA公钥证书验证你的证书,然后保存你的唯一标识和证书。
了解了证书之后,该是怎么应用了。
证书存放:
存放在表中:主要保存2个信息,证书和私钥。证书可以以X509Certificate这个类封装。
存放在keystore中。
读取证书信息:
从表中就自己写SQL。
从KeyStore中:
String storePass = "123456"; String aliasPass = "123456"; String aliasName = "aliasName"; String storeName = "C:\\Users\\liu\\storeName"; KeyStore ks = KeyStore.getInstance("JKS"); FileInputStream in = new FileInputStream(storeName); ks.load(in, storePass.toCharArray()); Certificate cert = ks.getCertificate(aliasName); PrivateKey pk = (PrivateKey) ks.getKey(aliasName, aliasPass.toCharArray()); PublicKey puk = cert.getPublicKey();
有了证书之后,就需要把证书发给CA了。我们就需要发给CA一个证书签名请求,简称CSR(certificate signed request),签完名后返回证书签名响应,然后导入。
生成CSR证书签名请求
X509Certificate x509Certificate; //前面提到怎么获得 PrivateKey pk; //前面提到怎么获得 PKCS10 p10 = new PKCS10(x509Certificate.getPublicKey()); String algorithm = pk.getAlgorithm(); if ((algorithm.equalsIgnoreCase("DSA")) || (algorithm.equalsIgnoreCase("DSS"))) { algorithm = "SHA1WithDSA"; } else if (algorithm.equalsIgnoreCase("RSA")) { algorithm = "MD5WithRSA"; } Signature sig = Signature.getInstance(algorithm); sig.initSign(pk); X500Name x500 = new X500Name(x509Certificate.getSubjectDN().toString()); X500Signer signer = new X500Signer(sig, x500); p10.encodeAndSign(signer);
用KeyTool:
command: keytool -certreq -v -alias aliasName -keystore storeName -file codesigncsr.p10
证书签名请求使用的是PKCS#10格式存放的
CA签过名之后,导入签名的证书
CertificateFactory cf = CertificateFactory.getInstance("X.509"); FileInputStream in = new FileInputStream("C:\\Users\\liu\\csr.cer"); certificate = cf.generateCertificate(in);
用KeyStore:
command:keytool -import -file cer.cer -keystore storeName
注意的是,我导入的是证书,不是证书签名响应。步骤我猜是一样的,但没实际应用过。
这是我从接触证书,然后自己查资料了解证书的一个过程,一个很简单的了解,写的很繁琐,可能也有很多理解错误的地方,希望大家多多指导。
这是我主要借鉴证书资料的一些地址,他们写的很详细。有的介绍KeyTool使用很详细,有介绍加密解密的,可以从那里学习到SSLSocket,和对称,非对称加密解密,也算是证书的应用吧。本来想写到自己里面,可是发现基本照抄的,还是列出地址给大家。
[url]
http://shellyli.iteye.com/blog/801638
http://lei-1021.iteye.com/blog/681691
http://lengjing.iteye.com/blog/1258892
http://chrui.iteye.com/blog/1018800
[/url]
解压123456
上一篇: Python中异常重试的解决方案详解
下一篇: 忘记Mysql密码的解决办法小结