日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2023/12/15 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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進行各種轉換的

總結

以上是生活随笔為你收集整理的java der pem_JAVA解析各种编码密钥对(DER、PEM、openssh公钥)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 在线免费你懂的 | 亚洲乱码精品久久久久 | 日本人三级 | 偷拍网亚洲 | 日韩精品在线一区 | 国产女厕一区二区三区在线视 | 女人被灌满精子 | 日本黄色小视频 | 深夜在线免费视频 | 欧美一区二区三区成人久久片 | 视频在线亚洲 | aaaa一级片 | 白丝动漫美女 | 毛片毛片毛片毛片毛片毛片毛片毛片毛片 | 日本新japanese乱熟 | 三级在线免费 | 亚洲精品一区二区三区四区五区 | 久久黄色影视 | 三上悠亚久久 | 亚洲a视频在线 | 欧美久久久久久久久久久 | 中文字幕一区二区三区人妻在线视频 | 色婷婷热久久 | 三浦惠理子aⅴ一二三区 | 一区免费 | 色噜噜狠狠一区二区 | 丰满雪白极品少妇流白浆 | 3d动漫精品h区xxxxx区 | 视频在线观看 | 亚洲第三色 | 国产精品日韩电影 | 欧美一区二区三区影院 | 好av在线| 日本不卡一区二区三区视频 | 视频在线观看一区二区 | 亚洲色成人www永久在线观看 | 男阳茎进女阳道视频大全 | 极度诱惑香港电影完整 | 一级片亚洲 | 久久久精品蜜桃 | 久久精品国产熟女亚洲AV麻豆 | 人妻精品一区二区三区 | av一级| 初尝人妻少妇中文字幕 | 久久不射电影网 | 无码精品在线视频 | 欧美1页 | 日韩中文字幕一区二区 | 国产极品美女高潮无套在线观看 | 中国极品少妇xxxxx | 性高潮久久久久久 | 国产高清免费观看 | 欧美黄色特级片 | 人成在线免费视频 | 国产高清一区二区三区四区 | 少妇一级视频 | 玩弄人妻少妇500系列视频 | 久久女人天堂 | 成人免费看片'在线观看 | 男人天堂综合 | 国产性猛交xxxx免费看久久 | 欧美黄色录像视频 | 一区二区欧美日韩 | 日韩美女免费视频 | 在线观看不卡一区 | 国产内射一区 | 91精产国品一二三区在线观看 | 久久久久国产视频 | 久久高清无码视频 | 亚洲专区在线视频 | 每日在线更新av | 另类小说亚洲色图 | 老熟妇午夜毛片一区二区三区 | 精品无码国产污污污免费网站 | 91资源在线视频 | 中文字幕一区二区三区不卡 | 伊人网在线视频观看 | 男人猛吃奶女人爽视频 | 亚洲码中文 | 成人性生交大片免费看中文 | 麻豆影音 | 夜夜嗨av禁果av粉嫩av懂色av | 天天草综合 | 日日摸日日碰 | 亚洲美女www午夜 | 大号bbwassbigav女 | 少妇精品无码一区二区免费视频 | 大胸美女无遮挡 | 成人乱人乱一区二区三区 | 91成人国产| 韩国三级免费 | 超碰男人天堂 | 国产精品久久久久久久久夜色 | 欧美脚交 | 精品国产亚洲一区二区麻豆 | 婷婷丁香激情五月 | 76少妇精品导航 | 黄网在线| 夜夜爽夜夜 |