java der pem_JAVA解析各种编码密钥对(DER、PEM、openssh公钥)

一、DER编码密钥对

先说下DER编码,是因为JCE本身是支持DER编码密钥对的解析的,可以参见PKCS8EncodedKeySpec和X509EncodedKeySpec.

DER编码是ASN.1编码规则中的一个子集,具体格式如何编排没有去了解,但最终呈现肯定的是一堆有规律的二进制组合而成。

PKCS#8定义了私钥信息语法和加密私钥语法,而X509定义证书规范,通常都会用DER和PEM进行编码存储,而在JAVA中则使用的

DER。

接下来看看如果通过DER编码的密钥对分别获取JAVA的公私钥对象。

1.下面一段是生成私钥对象的,传入参数是DER编码的私钥内容。

@Override

publicPrivateKey generatePrivateKey(byte[] key)throwsNoSuchAlgorithmException, InvalidKeySpecException {

KeySpec keySpec =newPKCS8EncodedKeySpec(key);

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

returnkeyFactory.generatePrivate(keySpec);

}

@Override

public PrivateKey generatePrivateKey(byte[] key) throws NoSuchAlgorithmException, InvalidKeySpecException {

KeySpec keySpec = new PKCS8EncodedKeySpec(key);

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

return keyFactory.generatePrivate(keySpec);

}

2.下面是生成公钥对象的,传入参数是DER编码公钥内容,可以看到和生成私钥的部分非常相似。

publicPublicKey geneneratePublicKey(byte[] key)throwsInvalidKeySpecException, NoSuchAlgorithmException{

KeySpec keySpec =newX509EncodedKeySpec(key);

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

returnkeyFactory.generatePublic(keySpec);

}

public PublicKey geneneratePublicKey(byte[] key) throws InvalidKeySpecException, NoSuchAlgorithmException{

KeySpec keySpec = new X509EncodedKeySpec(key);

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

return keyFactory.generatePublic(keySpec);

}

二、PEM编码

PEM编码也是密钥对较常用的编码方式,openssl则是以PEM编码为主,相对DER对人可读性更强,以BASE64编码呈现,外围包上类似-----BEGIN RSA PRIVATE KEY-----。

JCE没有对PEM直接支持的方式,但是可以通过第三方包例如bouncycastle解析,当然如果想要自己理解pem编码结构,也可以自己写代码解析。

这里介绍下如何使用bouncycastle进行解析。

FileInputStream fis =newFileInputStream("id_rsa");

byte[] key = PrivateKeyUtils.readStreamToBytes(fis);

Security.addProvider(newBouncyCastleProvider());

ByteArrayInputStream bais =newByteArrayInputStream(key);

PEMReader reader =newPEMReader(newInputStreamReader(bais),newPasswordFinder() {

@Override

publicchar[] getPassword() {

return"".toCharArray();

}

});

KeyPair keyPair = (KeyPair) reader.readObject();

reader.close();

PublicKey pubk = keyPair.getPublic();

System.out.println(pubk);

PrivateKey prik = keyPair.getPrivate();

System.out.println(prik);

KeySpec keySpec =newX509EncodedKeySpec(pubk.getEncoded());

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

System.out.println(keyFactory.generatePublic(keySpec));

KeySpec keySpec2 =newPKCS8EncodedKeySpec(prik.getEncoded());

System.out.println(keyFactory.generatePrivate(keySpec2));

FileInputStream fis = new FileInputStream("id_rsa");

byte[] key = PrivateKeyUtils.readStreamToBytes(fis);

Security.addProvider(new BouncyCastleProvider());

ByteArrayInputStream bais = new ByteArrayInputStream(key);

PEMReader reader = new PEMReader(new InputStreamReader(bais), new PasswordFinder() {

@Override

public char[] getPassword() {

return "".toCharArray();

}

});

KeyPair keyPair = (KeyPair) reader.readObject();

reader.close();

PublicKey pubk = keyPair.getPublic();

System.out.println(pubk);

PrivateKey prik = keyPair.getPrivate();

System.out.println(prik);

KeySpec keySpec = new X509EncodedKeySpec(pubk.getEncoded());

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

System.out.println(keyFactory.generatePublic(keySpec));

KeySpec keySpec2 = new PKCS8EncodedKeySpec(prik.getEncoded());

System.out.println(keyFactory.generatePrivate(keySpec2));

看下这个输出结果

RSA Public Key

modulus: c8f3e2d2e7fffe049127a115cab648fa9f55a7712d40868dccbddef9ebf030480a31f060e6c1ace2c53660e467cd173870367223dccea00ef2bdf6795757eb34fe1e8cfb63a0d333eefc9739029512df68108dd4b8054a12bdb206abd2ee7a727faa79604680c1337473ecd3d9a1a10b6cbc3af7862a74619ea7fe3a5bb2b89dded41dc5e4e4d5fcad169b85a599487929de1788e1e9a8d4efae4fda811d1e4d975b50d0d61b5887402ca975ec5e1d3ff193522b84746fe35ab00d073fed466786d9303f19c642c02cb1ad3a1ec6f0b7234e492e79500ee0bb1c1f07c23ae70af9b75aa35a6c75573d302cbf8f034341932dc371689b9f952388328c5277c117

public exponent: 10001

RSA Private CRT Key

modulus: c8f3e2d2e7fffe049127a115cab648fa9f55a7712d40868dccbddef9ebf030480a31f060e6c1ace2c53660e467cd173870367223dccea00ef2bdf6795757eb34fe1e8cfb63a0d333eefc9739029512df68108dd4b8054a12bdb206abd2ee7a727faa79604680c1337473ecd3d9a1a10b6cbc3af7862a74619ea7fe3a5bb2b89dded41dc5e4e4d5fcad169b85a599487929de1788e1e9a8d4efae4fda811d1e4d975b50d0d61b5887402ca975ec5e1d3ff193522b84746fe35ab00d073fed466786d9303f19c642c02cb1ad3a1ec6f0b7234e492e79500ee0bb1c1f07c23ae70af9b75aa35a6c75573d302cbf8f034341932dc371689b9f952388328c5277c117

public exponent: 10001

xxx

Sun RSA public key, 2048 bits

modulus: 25367925677263221630752072905429434117596189021449325931333193529363239091429133073657699480437320802724298965580526553453499379398405915207286949216370963889754756788008021698178495726807109888833039800230667805051637457878962812581009778614579379073430749907762728841603230968432191178635884450213875555645164935313884823663096624318071901833679005494934145072511042211644746801428698070096755012497436134537077746175344235590315572214836519284172251946833712681076781034466422251569387242330311670205489884189790153154281087401570994337126054046621401176808489895271448688335849540690562754961439975230588159770903

public exponent: 65537

Sun RSA private CRT key, 2048 bits

modulus:          25367925677263221630752072905429434117596189021449325931333193529363239091429133073657699480437320802724298965580526553453499379398405915207286949216370963889754756788008021698178495726807109888833039800230667805051637457878962812581009778614579379073430749907762728841603230968432191178635884450213875555645164935313884823663096624318071901833679005494934145072511042211644746801428698070096755012497436134537077746175344235590315572214836519284172251946833712681076781034466422251569387242330311670205489884189790153154281087401570994337126054046621401176808489895271448688335849540690562754961439975230588159770903

public exponent:  65537

xxx

RSA Public Key

modulus: c8f3e2d2e7fffe049127a115cab648fa9f55a7712d40868dccbddef9ebf030480a31f060e6c1ace2c53660e467cd173870367223dccea00ef2bdf6795757eb34fe1e8cfb63a0d333eefc9739029512df68108dd4b8054a12bdb206abd2ee7a727faa79604680c1337473ecd3d9a1a10b6cbc3af7862a74619ea7fe3a5bb2b89dded41dc5e4e4d5fcad169b85a599487929de1788e1e9a8d4efae4fda811d1e4d975b50d0d61b5887402ca975ec5e1d3ff193522b84746fe35ab00d073fed466786d9303f19c642c02cb1ad3a1ec6f0b7234e492e79500ee0bb1c1f07c23ae70af9b75aa35a6c75573d302cbf8f034341932dc371689b9f952388328c5277c117

public exponent: 10001

RSA Private CRT Key

modulus: c8f3e2d2e7fffe049127a115cab648fa9f55a7712d40868dccbddef9ebf030480a31f060e6c1ace2c53660e467cd173870367223dccea00ef2bdf6795757eb34fe1e8cfb63a0d333eefc9739029512df68108dd4b8054a12bdb206abd2ee7a727faa79604680c1337473ecd3d9a1a10b6cbc3af7862a74619ea7fe3a5bb2b89dded41dc5e4e4d5fcad169b85a599487929de1788e1e9a8d4efae4fda811d1e4d975b50d0d61b5887402ca975ec5e1d3ff193522b84746fe35ab00d073fed466786d9303f19c642c02cb1ad3a1ec6f0b7234e492e79500ee0bb1c1f07c23ae70af9b75aa35a6c75573d302cbf8f034341932dc371689b9f952388328c5277c117

public exponent: 10001

xxx

Sun RSA public key, 2048 bits

modulus: 25367925677263221630752072905429434117596189021449325931333193529363239091429133073657699480437320802724298965580526553453499379398405915207286949216370963889754756788008021698178495726807109888833039800230667805051637457878962812581009778614579379073430749907762728841603230968432191178635884450213875555645164935313884823663096624318071901833679005494934145072511042211644746801428698070096755012497436134537077746175344235590315572214836519284172251946833712681076781034466422251569387242330311670205489884189790153154281087401570994337126054046621401176808489895271448688335849540690562754961439975230588159770903

public exponent: 65537

Sun RSA private CRT key, 2048 bits

modulus: 25367925677263221630752072905429434117596189021449325931333193529363239091429133073657699480437320802724298965580526553453499379398405915207286949216370963889754756788008021698178495726807109888833039800230667805051637457878962812581009778614579379073430749907762728841603230968432191178635884450213875555645164935313884823663096624318071901833679005494934145072511042211644746801428698070096755012497436134537077746175344235590315572214836519284172251946833712681076781034466422251569387242330311670205489884189790153154281087401570994337126054046621401176808489895271448688335849540690562754961439975230588159770903

public exponent: 65537

xxx中间内容太多,略去了一部分,看下重点的public exponent部分,发现不同,但其实是一个是10进制输出,一个是16进制输出,所以在这里提个醒,这里生成过程没有错的。

三、openssh公钥

很多SSH公钥习惯使用openssh格式的,下面介绍下openssh格式的公钥如何解析,目前好像是没有官方库或者第三方库提供支持的。

openssh公钥呈现形式如

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCW6qYq6m8gVOWLyTB1JGl1aLrJDOCIfErXWNUsNeUXg4UdAtSbkiA+Ta9Nx6oMR4w+OkPbxyivnzkZt1YpmDxrm1z99z81/VyVw+lue+3neRjTgfGMascG+46b7DpEKLXlfS2hwOA+4ooRIeR+LbQZVovy5SP6ZTngskiqcySYqQ== RSA-1024

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCW6qYq6m8gVOWLyTB1JGl1aLrJDOCIfErXWNUsNeUXg4UdAtSbkiA+Ta9Nx6oMR4w+OkPbxyivnzkZt1YpmDxrm1z99z81/VyVw+lue+3neRjTgfGMascG+46b7DpEKLXlfS2hwOA+4ooRIeR+LbQZVovy5SP6ZTngskiqcySYqQ== RSA-1024

以ssh-rsa打头,描述“RSA-1024”结尾的形式,中间是Base64编码。

这里过滤掉除了Base64外的其他部分,解码Base64得到公钥二进制内容。

这里二进制编码格式如下:

前11字节固定

0 0 0 7  's' 's' 'h' '-' ‘r' 's' 'a'

紧接着4个字节为一个int值,表示public exponent所占字节长度

可通过移位符及相加或者BigInteger方式实现转换。

publicstaticintdecodeUInt32(byte[] key,intstart_index){

byte[] test = Arrays.copyOfRange(key, start_index, start_index +4);

returnnewBigInteger(test).intValue();

//      int int_24 = (key[start_index++] <

//      int int_16 = (key[start_index++] <

//      int int_8 = (key[start_index++] <

//      int int_0 = key[start_index++] & 0xff;

//      return int_24 + int_16 + int_8 + int_0;

}

public static int decodeUInt32(byte[] key, int start_index){

byte[] test = Arrays.copyOfRange(key, start_index, start_index + 4);

return new BigInteger(test).intValue();

//int int_24 = (key[start_index++] << 24) & 0xff;

//int int_16 = (key[start_index++] << 16) & 0xff;

//int int_8 = (key[start_index++] << 8) & 0xff;

//int int_0 = key[start_index++] & 0xff;

//return int_24 + int_16 + int_8 + int_0;

}

得到长度后,再从后一字节开始读取该长度字节作为public exponent的值,构造相应BigInteger。

再紧接着4个字节也是一个int值,表示modulus所占字节长度,同理转换得到长度。

再根据长度读取字节数组得到modulus值即可。

相应代码如下

publicstaticRSAPublicKey decodePublicKey(byte[] key)throwsNoSuchAlgorithmException, InvalidKeySpecException{

byte[] sshrsa =newbyte[] {0,0,0,7,'s','s','h','-','r','s',

'a'};

intstart_index = sshrsa.length;

/* Decode the public exponent */

intlen = decodeUInt32(key, start_index);

start_index +=4;

byte[] pe_b =newbyte[len];

for(inti=0; i 

pe_b[i] = key[start_index++];

}

BigInteger pe =newBigInteger(pe_b);

/* Decode the modulus */

len = decodeUInt32(key, start_index);

start_index +=4;

byte[] md_b =newbyte[len];

for(inti =0; i 

md_b[i] = key[start_index++];

}

BigInteger md =newBigInteger(md_b);

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

KeySpec ks =newRSAPublicKeySpec(md, pe);

return(RSAPublicKey) keyFactory.generatePublic(ks);

}

public static RSAPublicKey decodePublicKey(byte[] key) throws NoSuchAlgorithmException, InvalidKeySpecException{

byte[] sshrsa = new byte[] { 0, 0, 0, 7, 's', 's', 'h', '-', 'r', 's',

'a' };

int start_index = sshrsa.length;

/* Decode the public exponent */

int len = decodeUInt32(key, start_index);

start_index += 4;

byte[] pe_b = new byte[len];

for(int i= 0 ; i < len; i++){

pe_b[i] = key[start_index++];

}

BigInteger pe = new BigInteger(pe_b);

/* Decode the modulus */

len = decodeUInt32(key, start_index);

start_index += 4;

byte[] md_b = new byte[len];

for(int i = 0 ; i < len; i++){

md_b[i] = key[start_index++];

}

BigInteger md = new BigInteger(md_b);

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

KeySpec ks = new RSAPublicKeySpec(md, pe);

return (RSAPublicKey) keyFactory.generatePublic(ks);

}

四、其他编码

后续有机会再研究其他编码方式如何解析,不过可能bouncycastle已经提供了许多编码的解析,可以直接使用,具体没看,有兴趣的可以研究下。

下面有个网站介绍各种编码的,还有利用openssl进行各种转换的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/244425.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

switch最大选项数目_随时随地学习C语言之3—if和switch哪个效率高?

之前学习C语言的时候&#xff0c;我经常有一个疑问&#xff0c;既然有if-else if-else结构的多分支选择语句&#xff0c;C语言为何还要制定switch这种多分支选择语句呢&#xff1f;直到两年前在分析ARM平台C语言反汇编代码的时候&#xff0c;才终于明白了switch-case这种结构存…

android java 退出程序_android开发两种退出程序方式(killProcess,System.exit)

KillProcess&#xff1a;在android中我们如果想要程序的进程结束可以这样写&#xff1a;android.os.Process.killProcess(android.os.Process.myPid());这样就可以从操作系统中结束掉当前程序的进程。注意&#xff1a;android中所有的activity都在主进程中&#xff0c;在Androi…

java 验证码_Java - 验证码 - 由Kaptcha组件实现

本文是基于SpringBoot整合Kaptcha验证码实现Kaptcha 是一个可高度配置的实用验证码生成工具&#xff0c;在项目开发中能够非常方便实现验证码先来看一个由 Kaptcha 制作的验证码效果图快速进入如何进行配置与实现的第1步&#xff1a;配置 Kaptcha 的依赖库com.github.penggle …

bat关闭java_通过bat脚本停止java进程的三个方法

通过bat脚本停止java进程的三个方法1.拷贝java.exe启动时复制java.exe程序修改进程映像名&#xff0c;然后通过映像名杀进程。栗子过程操作拷贝程序拷贝一份java.exe程序&#xff0c;重名为tstop.exe,放在PATH下。修改启动脚本echo offtitle tstoptstop -jar …/lib/laucher.ja…

onclick 获取img 里面的id_红魔5S游戏手机如何解锁bl获取第三方面具root权限

自从苹果阵营发布S系列&#xff0c;安卓系列也学习苹果的步伐&#xff0c;开始发布S系列&#xff0c;这不努比亚也发不了今年夏天的游戏手机&#xff0c;红魔5S游戏手机。红魔5S相对于红魔5其实从配置来看&#xff0c;三大件配置变化并不大&#xff0c;主要还是细节上的一些提升…

java 工厂模式的写法_设计模式-工厂模式

一、概述什么是工厂模式&#xff1f;工厂模式(Factory Pattern)是最常见的一种设计模式之一。它主要是提供一种创建对象的最佳方法&#xff01;为什么要学习工厂模式&#xff1f;与通过new来创建对象不同&#xff0c;使用工厂模式创建对象不会对客户端暴露创建逻辑&#xff0c;…

jackson 序列化_jackson序列化与反序列化的应用实践

作者 | zhouweixin 来源 | urlify.cn/iEbiAz66套java从入门到精通实战课程分享1 相关概念序列化: 把对象转换为字节序列的过程称为对象的序列化反序列化: 把字节序列恢复为对象的过程称为对象的反序列化2 序列化的作用用于把内存中的对象状态保存到一个文件中或者数据库中用于网…

layui中table监听单元格_layui table表格 监听头删除不请求后台

表格jsfunction getTable() {var table layui.table //表格var username$("#username").val();//执行一个 table 实例table.render({elem: #demo,where: {username:username}//传值,method: post//请求方式,height: 420,url: ${path}/sys/admin/getAllUser //数据接…

java mqtt客户端_基于 t-io 实现一个 mqtt5 协议之 mica-mqtt

一、简介 MQTT 全称为 Message Queuing Telemetry Transport&#xff08;消息队列遥测传输&#xff09;是一种基于发布/订阅范式的“轻量级”消息协议&#xff0c;由 IBM 发布。目前使用比较广泛的就是 mqtt 3.1.1&#xff08;2014年制定&#xff09;&#xff0c;mqtt 5.0&…

python的gui库_tkinter——python的GUI标准库

-- coding:utf-8 --import tkinter as tkwindowtk.Tk()#一个窗口对象window.title("tkinter")#窗口名称window.geometry("200x200")#字符串形式表示长宽 中间是xlatk.Label(window,text"我是鬼畜窗口\nnb",bg"red",font("Ariel&q…

java rc4_nodejs 和 java 进行 rc4 加密得到的结果不一样

同时在对一个buffer<03 01 00 00 02 00 00 00>进行加密。java 和 c 得到的结果是CA 66 C4 5D 90 E7 30 01nodejs 得到的结果是6f 61 f8 95 ab ba aa 90不一样 什么原因导致的呢&#xff1f;import java.nio.ByteBuffer;import javax.crypto.Cipher;import javax.crypto.s…

python3闭包通俗解释_Python|闭包、装饰器,简单的实例,通俗的理解

闭包和装饰器都是属于函数的语法范畴&#xff0c;是在函数定义中以另一个函数做为形参的语法机制。1 闭包(Closurer)闭包是定义内部函数的一种语法规则&#xff0c;要理解闭包&#xff0c;请看下面的实例&#xff1a;def outer(t):....print(t)....def inner(i):........return…

java自我介绍_JAVA面试技巧之自我介绍

【如何进行自我介绍】自我介绍这个问题&#xff0c;不用多说了&#xff0c;面试必定会问&#xff01;如果想要在自我介绍的时候就能够打动面试官&#xff0c;吸引面试官对我们的兴趣&#xff0c;那么像我们这种接受过Java培训的程序员的自我介绍当然不能和应届生或者其他非技术…

java excel 操作 poi_Java使用apache poi进行excel相关操作

一.基本介绍1.1、Apache POI介绍Apache POI是一个可以进行微软的文档进行开源库&#xff0c;可以操作的文档类型包括word、ppt、excel、visio、outlook....本文主要针对Apache POI对excel的操作进行介绍&#xff0c;主要包括如何创建一个excel、录入数据、读取excel数据的方式。…

程序解析excel中的图片_产品日志丨支持导入Excel中的图片amp;批量修改后期实体字段...

本次安捷秀又迎来了一个大版本更新&#xff0c;除了大家呼声很高的「实体模块导入 Excel 」外&#xff0c;还有「批量编辑实体」&#xff0c;「支持右击修改」以及针对海外用户的「全页面支持英文」等功能的新增与优化&#xff0c;一起来看看吧。导入功能优化AGILESHOT&#xf…

java随机星星怎么闪_canvas画随机闪烁的星星

canvas画一颗星星&#xff1a;规则的星星有内切圆和外切圆&#xff0c;每两个点之间的角度是固定的&#xff0c;因此可得到星星的每个点的坐标&#xff0c;画出星星。function drawStars(x,y,radius1,radius2,num,drawType,color){var angle 360/(num*2);var arr [];for(var …

java 四种内存_不可访问内存 Java四种引用包括强引用,软引用,弱引用,虚引用...

小结&#xff1a;1、不可访问内存是指一组没有任何可访问指针指向的由计算机程序进行动态分配的内存块。2、垃圾收集器能决定是否一个对象还是可访问的&#xff1b;任何被确定不可访问的对象将会被释放。https://zh.wikipedia.org/wiki/不可访问内存在计算机科学中&#xff0c;…

python async_python async with和async for的使用

网上async with和async for的中文资料比较少&#xff0c;我把PEP 492中的官方陈述翻译一下。异步上下文管理器”async with”异步上下文管理器指的是在enter和exit方法处能够暂停执行的上下文管理器。为了实现这样的功能&#xff0c;需要加入两个新的方法&#xff1a;__aenter_…

python将dataframe写入csv_Pandas dataframe数据写入文件和数据库

转自&#xff1a;http://www.dcharm.com/?p584Pandas是Python下一个开源数据分析的库&#xff0c;它提供的数据结构DataFrame极大的简化了数据分析过程中一些繁琐操作,DataFrame是一张多维的表&#xff0c;大家可以把它想象成一张Excel表单或者Sql表。之前这篇文章已经介绍了从…

java字节输入与字符输入_Java中的字节输入出流和字符输入输出流

Java中的字节输入出流和字符输入输出流下面哪个流类属于面向字符的输入流( )A BufferedWriterB FileInputStreamC ObjectInputStreamD InputStreamReader解析&#xff1a;IO流(1)字节输入流基类&#xff1a;InputStreamFileInputStream、ByteArrayInputStream、PipedInputStrea…