资讯

精准传达 • 有效沟通

从品牌网站建设到网络营销策划,从策略到执行的一站式服务

java代码生成公钥证书 java生成公钥私钥

如何用Java读取使用证书

证书(Certificate,也称public-key certificate)是用某种签名算法对某些内容(比如公钥)进行数字签名后得到的、可以用来当成信任关系中介的数字凭证。证书发行机构通过发行证书告知证书使用者或实体其公钥(public-key)以及其它一些辅助信息。证书在电子商务安全交易中有着广泛的应用,证书发行机构也称CA(Certificate Authority)。

创新互联公司是专业的湟中网站建设公司,湟中接单;提供成都做网站、成都网站设计,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行湟中网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!

应用证书

证书在公钥加密应用中的作用是保证公钥在某些可信的机构发布,其在协议SSL、电子交易协议SET等方面有重要的应用。图1显示了一个最简单的证书应用方法:

图1 证书应用方法

证书的应用步骤是:

(1) A把自己的公钥PKA送到CA(Certificate Authority);

(2) CA用自己的私钥和A的公钥生成A的证书,证书内包括CA的数字签名。签名对象包括需要在证书中说明的内容,比如A的公钥、时间戳、序列号等,为了简化这里不妨假设证书中只有三项内容:A的公钥PKA、时间戳TIME1、序列号IDA。那么CA发送给A的简单证书凭证可表达为:CertA=Eca[TIME1,IDA,PKA];

(3) B同样把自己的公钥PKB送到CA;

(4) B得到CA发布的证书CertB;

(5) A告知B证书CertA;

(6) B告知A证书CertB。

A、B各自得到对方证书后,利用从CA得到的公钥(在CA的自签证书中)验证彼此对方的证书是否有效,如果有效,那么就得到了彼此的公钥。利用对方的公钥,可以加密数据,也可以用来验证对方的数字签名。

本文为了方便说明,并没有使用从CA获得的证书,而是通信双方各自产生自签证书,也就是说图1的A和B并没有经过CA,不过前提是A和B之间是互相拥有对方的证书。

java生成的rsa公钥 能在python上使用吗

肯定可以,这个跟语言是无关的

Python上RSA加密的库挺多的,最开始使用的是rsa,因为比较简单嘛!测试的时候也是用 python模拟App的访问,顺利通过!

然而App开发者反馈,python测试脚本没法移植到java上,因为java的加密解密模块需要更加精细的算法细节指定,否则java加密过的数据python是解不出来的。

当初就是因为rsa模块简单,不需要注重细节才选的,自己又不是专业搞加密解密的。没办法了,只能硬着头皮,捋了一遍RSA的加密原理。网上还是有比较多的讲述比较好的文章,比如RSA算法原理

原理是懂了,但具体到python和java的区别上,还是一头雾水。最终python的RSA模块换成Crypto,因为支持的参数比较多。搜了很多网站讲的都不是很详细,stackflow上有几篇还可以,借鉴了一下,最后测试通过了。还是直接上代码吧。

Java代码

//下面这行指定了RSA算法的细节,必须更python对应

private static String RSA_CONFIGURATION = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding";

//这个貌似需要安装指定的provider模块,这里没有使用

private static String RSA_PROVIDER = "BC";

//解密 Key:私钥

public static String decrypt(Key key, String encryptedString){

try {

Cipher c = Cipher.getInstance(RSA_CONFIGURATION);

c.init(Cipher.DECRYPT_MODE, key, new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256,

PSource.PSpecified.DEFAULT));

byte[] decodedBytes;

decodedBytes = c.doFinal(Base64.decode(encryptedString.getBytes("UTF-8")));

return new String(decodedBytes, "UTF-8");

} catch (IllegalBlockSizeException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (BadPaddingException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (Base64DecodingException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (UnsupportedEncodingException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (NoSuchAlgorithmException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (NoSuchPaddingException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (InvalidKeyException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (InvalidAlgorithmParameterException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return null;

}

//加密 Key一般是公钥

public static String encrypt(Key key, String toBeEncryptedString){

try {

Cipher c = Cipher.getInstance(RSA_CONFIGURATION);

c.init(Cipher.ENCRYPT_MODE, key, new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256,

PSource.PSpecified.DEFAULT));

byte[] encodedBytes;

encodedBytes = c.doFinal(toBeEncryptedString.getBytes("UTF-8"));

return Base64.encode(encodedBytes);

} catch (IllegalBlockSizeException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (BadPaddingException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (UnsupportedEncodingException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (NoSuchAlgorithmException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (NoSuchPaddingException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (InvalidKeyException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (InvalidAlgorithmParameterException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return null;

}

//通过Pem格式的字符串(PKCS8)生成私钥,base64是去掉头和尾的b64编码的字符串

//Pem格式私钥一般有2种规范:PKCS8和PKCS1.注意java在生成私钥时的不同

static PrivateKey generatePrivateKeyFromPKCS8(String base64)

{

byte[] privateKeyBytes;

try {

privateKeyBytes = Base64.decode(base64.getBytes("UTF-8"));

KeyFactory kf = KeyFactory.getInstance("RSA");

PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(privateKeyBytes);

PrivateKey privateKey = kf.generatePrivate(ks);

return privateKey;

} catch (Base64DecodingException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (UnsupportedEncodingException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (NoSuchAlgorithmException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (InvalidKeySpecException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return null;

}

//通过Pem格式的字符串(PKCS1)生成私钥,base64是去掉头和尾的b64编码的字符串

static PrivateKey generatePrivateKeyFromPKCS1(String base64)

{

byte[] privateKeyBytes;

try {

privateKeyBytes = Base64.decode(base64.getBytes("UTF-8"));

KeyFactory kf = KeyFactory.getInstance("RSA");

X509EncodedKeySpec ks = new X509EncodedKeySpec(privateKeyBytes);

PrivateKey privateKey = kf.generatePrivate(ks);

return privateKey;

} catch (Base64DecodingException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (UnsupportedEncodingException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (NoSuchAlgorithmException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (InvalidKeySpecException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return null;

}

//通过Pem格式的字符串(PKCS1)生成公钥,base64是去掉头和尾的b64编码的字符串

//Pem格式公钥一般采用PKCS1格式

static PublicKey generatePublicKeyFromPKCS1(String base64)

{

byte[] publicKeyBytes;

try {

publicKeyBytes = Base64.decode(base64.getBytes("UTF-8"));

KeyFactory kf = KeyFactory.getInstance("RSA");

X509EncodedKeySpec ks = new X509EncodedKeySpec(publicKeyBytes);

PublicKey publicKey = kf.generatePublic(ks);

return publicKey;

} catch (Base64DecodingException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (UnsupportedEncodingException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (NoSuchAlgorithmException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (InvalidKeySpecException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return null;

}

//通过modulus和exponent生成公钥

//参数含义就是RSA算法里的意思

public static RSAPublicKey getPublicKey(String modulus, String exponent) {

try {

BigInteger b1 = new BigInteger(modulus);

BigInteger b2 = new BigInteger(exponent);

KeyFactory keyFactory = KeyFactory.getInstance("RSA");

RSAPublicKeySpec keySpec = new RSAPublicKeySpec(b1, b2);

return (RSAPublicKey) keyFactory.generatePublic(keySpec);

} catch (Exception e) {

e.printStackTrace();

return null;

}

} 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169

Python 代码

from Config import config

from Crypto.Hash import SHA256

from Crypto.PublicKey import RSA

from Crypto.Cipher import PKCS1_OAEP

key = RSA.generate(1024)

pubkey = key.publickey().key

def Decrypt(prikey,data):

try:

cipher = PKCS1_OAEP.new(prikey, hashAlgo=SHA256)

return cipher.decrypt(data)

except:

traceback.print_exc()

return None

def Encrypt(pubkey,data):

try:

cipher = PKCS1_OAEP.new(pubkey, hashAlgo=SHA256)

return cipher.encrypt(data)

except:

traceback.print_exc()

return None

1234567891011121314151617181920212223

总结

主要是对RSA算法不是很熟悉,其中很多术语不懂,导致跟java里的加密模块的函数和类对应不上。

RSA算法的细节到现在也是一知半解,但真的没时间去深入学习了。

用Java编写一个程序,生成公钥和私钥对

一:需要包含的包

import java.security.*;

import java.io.*;

import java.util.*;

import java.security.*;

import java.security.cert.*;

import sun.security.x509.*

import java.security.cert.Certificate;

import java.security.cert.CertificateFactory;

二:从文件中读取证书

用keytool将.keystore中的证书写入文件中,然后从该文件中读取证书信息

CertificateFactory cf=CertificateFactory.getInstance("X.509");

FileInputStream in=new FileInputStream("out.csr");

Certificate c=cf.generateCertificate(in);

String s=c.toString();

三:从密钥库中直接读取证书

String pass="123456";

FileInputStream in=new FileInputStream(".keystore");

KeyStore ks=KeyStore.getInstance("JKS");

ks.load(in,pass.toCharArray());

java.security.cert.Certificate c=ks.getCertificate(alias);//alias为条目的别名

四:JAVA程序中显示证书指定信息

System.out.println("输出证书信息:\n"+c.toString());

System.out.println("版本号:"+t.getVersion());

System.out.println("序列号:"+t.getSerialNumber().toString(16));

System.out.println("主体名:"+t.getSubjectDN());

System.out.println("签发者:"+t.getIssuerDN());

System.out.println("有效期:"+t.getNotBefore());

System.out.println("签名算法:"+t.getSigAlgName());

byte [] sig=t.getSignature();//签名值

PublicKey pk=t.getPublicKey();

byte [] pkenc=pk.getEncoded();

System.out.println("公钥");

for(int i=0;ipkenc.length;i++)System.out.print(pkenc[i]+",");

五:JAVA程序列出密钥库所有条目

String pass="123456";

FileInputStream in=new FileInputStream(".keystore");

KeyStore ks=KeyStore.getInstance("JKS");

ks.load(in,pass.toCharArray());

Enumeration e=ks.aliases();

while(e.hasMoreElements())

java.security.cert.Certificate c=ks.getCertificate((String)e.nextElement());

六:JAVA程序修改密钥库口令

String oldpass="123456";

String newpass="654321";

FileInputStream in=new FileInputStream(".keystore");

KeyStore ks=KeyStore.getInstance("JKS");

ks.load(in,oldpass.toCharArray());

in.close();

FileOutputStream output=new FileOutputStream(".keystore");

ks.store(output,newpass.toCharArray());

output.close();

七:JAVA程序修改密钥库条目的口令及添加条目

FileInputStream in=new FileInputStream(".keystore");

KeyStore ks=KeyStore.getInstance("JKS");

ks.load(in,storepass.toCharArray());

Certificate [] cchain=ks.getCertificate(alias);获取别名对应条目的证书链

PrivateKey pk=(PrivateKey)ks.getKey(alias,oldkeypass.toCharArray());获取别名对应条目的私钥

ks.setKeyEntry(alias,pk,newkeypass.toCharArray(),cchain);向密钥库中添加条目

第一个参数指定所添加条目的别名,假如使用已存在别名将覆盖已存在条目,使用新别名将增加一个新条目,第二个参数为条目的私钥,第三个为设置的新口令,第四个为该私钥的公钥的证书链

FileOutputStream output=new FileOutputStream("another");

ks.store(output,storepass.toCharArray())将keystore对象内容写入新文件

八:JAVA程序检验别名和删除条目

FileInputStream in=new FileInputStream(".keystore");

KeyStore ks=KeyStore.getInstance("JKS");

ks.load(in,storepass.toCharArray());

ks.containsAlias("sage");检验条目是否在密钥库中,存在返回true

ks.deleteEntry("sage");删除别名对应的条目

FileOutputStream output=new FileOutputStream(".keystore");

ks.store(output,storepass.toCharArray())将keystore对象内容写入文件,条目删除成功

九:JAVA程序签发数字证书

(1)从密钥库中读取CA的证书

FileInputStream in=new FileInputStream(".keystore");

KeyStore ks=KeyStore.getInstance("JKS");

ks.load(in,storepass.toCharArray());

java.security.cert.Certificate c1=ks.getCertificate("caroot");

(2)从密钥库中读取CA的私钥

PrivateKey caprk=(PrivateKey)ks.getKey(alias,cakeypass.toCharArray());

(3)从CA的证书中提取签发者的信息

byte[] encod1=c1.getEncoded(); 提取CA证书的编码

X509CertImpl cimp1=new X509CertImpl(encod1); 用该编码创建X509CertImpl类型对象

X509CertInfo cinfo1=(X509CertInfo)cimp1.get(X509CertImpl.NAME+"."+X509CertImpl.INFO); 获取X509CertInfo对象

X500Name issuer=(X500Name)cinfo1.get(X509CertInfo.SUBJECT+"."+CertificateIssuerName.DN_NAME); 获取X509Name类型的签发者信息

(4)获取待签发的证书

CertificateFactory cf=CertificateFactory.getInstance("X.509");

FileInputStream in2=new FileInputStream("user.csr");

java.security.cert.Certificate c2=cf.generateCertificate(in);

(5)从待签发的证书中提取证书信息

byte [] encod2=c2.getEncoded();

X509CertImpl cimp2=new X509CertImpl(encod2); 用该编码创建X509CertImpl类型对象

X509CertInfo cinfo2=(X509CertInfo)cimp2.get(X509CertImpl.NAME+"."+X509CertImpl.INFO); 获取X509CertInfo对象

(6)设置新证书有效期

Date begindate=new Date(); 获取当前时间

Date enddate=new Date(begindate.getTime()+3000*24*60*60*1000L); 有效期为3000天

CertificateValidity cv=new CertificateValidity(begindate,enddate); 创建对象

cinfo2.set(X509CertInfo.VALIDITY,cv); 设置有效期

(7)设置新证书序列号

int sn=(int)(begindate.getTime()/1000); 以当前时间为序列号

CertificateSerialNumber csn=new CertificateSerialNumber(sn);

cinfo2.set(X509CertInfo.SERIAL_NUMBER,csn);

(8)设置新证书签发者

cinfo2.set(X509CertInfo.ISSUER+"."+CertificateIssuerName.DN_NAME,issuer);应用第三步的结果

(9)设置新证书签名算法信息

AlgorithmId algorithm=new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);

cinfo2.set(CertificateAlgorithmId.NAME+"."+CertificateAlgorithmId.ALGORITHM,algorithm);

(10)创建证书并使用CA的私钥对其签名

X509CertImpl newcert=new X509CertImpl(cinfo2);

newcert.sign(caprk,"MD5WithRSA"); 使用CA私钥对其签名

(11)将新证书写入密钥库

ks.setCertificateEntry("lf_signed",newcert);

FileOutputStream out=new FileOutputStream("newstore");

ks.store(out,"newpass".toCharArray()); 这里是写入了新的密钥库,也可以使用第七条来增加条目

十:数字证书的检验

(1)验证证书的有效期

(a)获取X509Certificate类型对象

CertificateFactory cf=CertificateFactory.getInstance("X.509");

FileInputStream in1=new FileInputStream("aa.crt");

java.security.cert.Certificate c1=cf.generateCertificate(in1);

X509Certificate t=(X509Certificate)c1;

in2.close();

(b)获取日期

Date TimeNow=new Date();

(c)检验有效性

try{

t.checkValidity(TimeNow);

System.out.println("OK");

}catch(CertificateExpiredException e){ //过期

System.out.println("Expired");

System.out.println(e.getMessage());

}catch((CertificateNotYetValidException e){ //尚未生效

System.out.println("Too early");

System.out.println(e.getMessage());}

(2)验证证书签名的有效性

(a)获取CA证书

CertificateFactory cf=CertificateFactory.getInstance("X.509");

FileInputStream in2=new FileInputStream("caroot.crt");

java.security.cert.Certificate cac=cf.generateCertificate(in2);

in2.close();

(c)获取CA的公钥

PublicKey pbk=cac.getPublicKey();

(b)获取待检验的证书(上步已经获取了,就是C1)

(c)检验证书

boolean pass=false;

try{

c1.verify(pbk);

pass=true;

}catch(Exception e){

pass=false;

System.out.println(e);

}

JAVA 如何生成证书

下面产生一个自签证书。安装完J2SDK(这里用的是J2SDK1.4)后,在J2SDK安装目录的bin目录下,有一个keytool的可执行程序。利用keytool产生自签证书的步骤如下:

第一步,用-genkey命令选项,产生公私密钥对。在控制台界面输入:keytool -genkey -alias testkeypair -keyalg RSA -keysize 1024 -sigalg MD5withRSA。这里的-alias表示使用这对公私密钥产生新的keystore入口的别名(keystore是用来存放管理密钥对和证书链的,缺省位置是在使用者主目录下,以.keystore为名的隐藏文件,当然也可指定某个路径存放.keystore文件);-keyalg是产生公私钥对所用的算法,这里是RSA;-keysize定义密钥的长度;-sigalg是签名算法,选择MD5withRSA,即用RSA签名,然后用MD5哈希算法摘要。接下来,系统会提示进行一些输入:

输入keystore密码: abc123

您的名字与姓氏是什么?

[Unknown]: Li

您的组织单位名称是什么?

nbs

问题的其他解决办法参考 :

;t=JAVA+

如何从java生成签名在AWS问题,怎么解决

Java2下Applet数字签名实现过程如下:

在代码的分发端:

(1)开发Java源程序并对其进行编译。

(2)用JAR工具对类文件和资源文件进行封装。

(3)用keytool创建公钥和密钥,生成X。509V1签名证书,输出证书。

(4)通过jarsigner工具用生成的密钥对JAR文件进行数字签名。

在代码的接收端:

(1)用keytool输入证书视其为可信任。

(2)用policytool创建和修改安全性策略配置文件,授权请求的访问权限。

(3)从网络取得字节码,用公钥验证数字签名证书和文档代码的完整性。

(4)验证字节码的合法性,根据策略文件分配相应权限。

(5)执行代码,完成后被垃圾回收器回收内存。

在用公钥验证数字签名证书之前,接收方需要确认公钥自身的可靠性,因此通常情况是提供一个包含公钥的证书而不是公钥自身。1个证书包括:

(1)1个公钥。

(2)1个唯一的名字实体(个人或公司),它是证书的所有者,包含用户名字、公司、组织、城市、地址、国家代码、省份等信息。

(3)数字签名:1个证书被1个分发者的实体签名,保证证书确实包含另1个实体(所有者)的公钥。

我用java的api 生成一对公私钥,把公钥给服务端,但java生成的公钥 是162个字节, server端 只接收140个

客户端和服务端都指定编码格式了吗?

注意编码格式,UFt8和gbk等 每种编码格式获得的字节数是不一样的,


本文名称:java代码生成公钥证书 java生成公钥私钥
标题来源:http://cdkjz.cn/article/hjccpo.html
多年建站经验

多一份参考,总有益处

联系快上网,免费获得专属《策划方案》及报价

咨询相关问题或预约面谈,可以通过以下方式与我们联系

大客户专线   成都:13518219792   座机:028-86922220