การแปลง Java Keystore เป็นรูปแบบ PEM


133

ฉันกำลังพยายามแปลงจากไฟล์ที่เก็บคีย์ Java เป็นไฟล์ PEM โดยใช้แอปพลิเคชัน keytool และ openssl แต่ฉันไม่พบวิธีที่ดีในการแปลง ความคิดใด ๆ ?

แทนที่จะแปลงที่เก็บคีย์เป็น PEM โดยตรงฉันพยายามสร้างไฟล์ PKCS12 ก่อนแล้วจึงแปลงเป็นไฟล์ PEM และ Keystore ที่เกี่ยวข้อง แต่ฉันไม่สามารถสร้างการเชื่อมต่อโดยใช้พวกเขาได้ (โปรดทราบว่าฉันต้องการแค่ไฟล์ PEM และไฟล์ Keystore เพื่อใช้การเชื่อมต่อที่ปลอดภัยไม่มีข้อ จำกัด เช่น "Start from a java keystore file" :) ดังนั้นการเริ่มจากรูปแบบอื่นจึงเป็นที่ยอมรับในกรณีของฉัน)

แต่ควรใช้วิธีการแปลงโดยตรงจาก jks เป็น pem

คำตอบ:


217

ค่อนข้างตรงไปตรงมาโดยใช้ jdk6 เป็นอย่างน้อย ...

bash $ keytool -keystore foo.jks -genkeypair -alias foo \
        -dname 'CN = foo.example.com, L = Melbourne, ST = Victoria, C = AU'
ป้อนรหัสผ่านที่เก็บคีย์:  
ป้อนรหัสผ่านใหม่: 
ป้อนรหัสผ่านที่สำคัญสำหรับ 
        (ส่งคืนหากเหมือนกับรหัสผ่านที่เก็บคีย์):  
bash $ keytool -keystore foo.jks -exportcert -alias foo | \
       openssl x509 -inform der -text
ป้อนรหัสผ่านที่เก็บคีย์: asdasd
ใบรับรอง:
    ข้อมูล:
        เวอร์ชัน: 3 (0x2)
        หมายเลขผลิตภัณฑ์: 1237334757 (0x49c03ae5)
        อัลกอริทึมลายเซ็น: dsaWithSHA1
        ผู้ออก: C = AU, ST = Victoria, L = Melbourne, CN = foo.example.com
        ความถูกต้อง
            ไม่ก่อน: 18 มี.ค. 00:05:57 น. 2009 GMT
            หลัง: 16 มิ.ย. 00:05:57 น. 2009 GMT
        เรื่อง: C = AU, ST = Victoria, L = Melbourne, CN = foo.example.com
        ข้อมูลคีย์สาธารณะของหัวเรื่อง:
            อัลกอริทึมคีย์สาธารณะ: dsaEncryption
            คีย์สาธารณะ DSA:
                ผับ: 
                    00: e2: 66: 5c: e0: 2e: da: e0: 6b: a6: aa: 97: 64: 59: 14:
                    7e: a6: 2e: 5a: 45: f9: 2f: b5: 2d: f4: 34: 27: e6: 53: c7:
 

bash $ keytool -importkeystore -srckeystore foo.jks \
       -destkeystore foo.p12 \
       -srcstoretype jks \
       -deststoretype pkcs12
ป้อนรหัสผ่านที่เก็บคีย์ปลายทาง:  
ป้อนรหัสผ่านใหม่: 
ป้อนรหัสผ่านที่เก็บคีย์ต้นทาง:  
รายการสำหรับนามแฝง foo นำเข้าสำเร็จแล้ว
คำสั่งนำเข้าเสร็จสมบูรณ์: นำเข้า 1 รายการสำเร็จ 0 รายการล้มเหลวหรือยกเลิก

bash $ openssl pkcs12 -in foo.p12 -out foo.pem
ป้อนรหัสผ่านนำเข้า:
MAC ยืนยันตกลง
ป้อนรหัสผ่าน PEM:
การตรวจสอบ - ป้อนรหัสผ่าน PEM:

bash $ openssl x509 -text -in foo.pem
ใบรับรอง:
    ข้อมูล:
        เวอร์ชัน: 3 (0x2)
        หมายเลขผลิตภัณฑ์: 1237334757 (0x49c03ae5)
        อัลกอริทึมลายเซ็น: dsaWithSHA1
        ผู้ออก: C = AU, ST = Victoria, L = Melbourne, CN = foo.example.com
        ความถูกต้อง
            ไม่ก่อน: 18 มี.ค. 00:05:57 น. 2009 GMT
            หลัง: 16 มิ.ย. 00:05:57 น. 2009 GMT
        เรื่อง: C = AU, ST = Victoria, L = Melbourne, CN = foo.example.com
        ข้อมูลคีย์สาธารณะของหัวเรื่อง:
            อัลกอริทึมคีย์สาธารณะ: dsaEncryption
            คีย์สาธารณะ DSA:
                ผับ: 
                    00: e2: 66: 5c: e0: 2e: da: e0: 6b: a6: aa: 97: 64: 59: 14:
                    7e: a6: 2e: 5a: 45: f9: 2f: b5: 2d: f4: 34: 27: e6: 53: c7:
 

bash $ openssl dsa -text -in foo.pem
อ่านคีย์ DSA
ป้อนรหัสผ่าน PEM:
คีย์ส่วนตัว: (1024 บิต)
ส่วนตัว:
    00: 8f: b1: af: 55: 63: 92: 7c: d2: 0f: e6: f3: a2: f5: ff:
    1a: 7a: fe: 8c: 39: dd
ผับ: 
    00: e2: 66: 5c: e0: 2e: da: e0: 6b: a6: aa: 97: 64: 59: 14:
    7e: a6: 2e: 5a: 45: f9: 2f: b5: 2d: f4: 34: 27: e6: 53: c7:



คุณจบลงด้วย:

  • foo.jks - ที่เก็บคีย์ในรูปแบบ java
  • foo.p12 - ที่เก็บคีย์ในรูปแบบ PKCS # 12
  • foo.pem - คีย์และใบรับรองทั้งหมดจากที่เก็บคีย์ในรูปแบบ PEM

(ไฟล์สุดท้ายนี้สามารถแบ่งออกเป็นคีย์และใบรับรองได้หากต้องการ)


สรุปคำสั่ง - เพื่อสร้างที่เก็บคีย์ JKS:

keytool -keystore foo.jks -genkeypair -alias foo \
    -dname 'CN=foo.example.com,L=Melbourne,ST=Victoria,C=AU'

สรุปคำสั่ง - เพื่อแปลงที่เก็บคีย์ JKS เป็นที่เก็บคีย์ PKCS # 12 จากนั้นเป็นไฟล์ PEM:

keytool -importkeystore -srckeystore foo.jks \
   -destkeystore foo.p12 \
   -srcstoretype jks \
   -deststoretype pkcs12

openssl pkcs12 -in foo.p12 -out foo.pem

หากคุณมีใบรับรองมากกว่าหนึ่งรายการในที่เก็บคีย์ JKS ของคุณและคุณต้องการส่งออกเฉพาะใบรับรองและคีย์ที่เชื่อมโยงกับนามแฝงอย่างใดอย่างหนึ่งคุณสามารถใช้รูปแบบต่อไปนี้:

keytool -importkeystore -srckeystore foo.jks \
   -destkeystore foo.p12 \
   -srcalias foo \
   -srcstoretype jks \
   -deststoretype pkcs12

openssl pkcs12 -in foo.p12 -out foo.pem

สรุปคำสั่ง - เพื่อเปรียบเทียบที่เก็บคีย์ JKS กับไฟล์ PEM:

keytool -keystore foo.jks -exportcert -alias foo | \
   openssl x509 -inform der -text

openssl x509 -text -in foo.pem

openssl dsa -text -in foo.pem

12
วิธีนี้ไม่รองรับใบรับรองที่เชื่อถือได้: นี่เป็นข้อ จำกัด ของรูปแบบ PKS12 ที่ฉันเชื่อว่าโปรดดู: java.sun.com/javase/6/docs/technotes/guides/security/jsse/… (ส่วนบน java.security.KeyStoreException : TrustedCertEntry ไม่รองรับ)
andygavin

2
ฉันมีไฟล์ JKS ที่เก่ากว่า ฉันไม่สามารถส่งออกโดยใช้วิธีการด้านบน ในที่สุดฉันก็ทำได้โดยการตั้งค่า keytool arg '-destkeypass' เป็นค่าดัมมี่ 'keytool' ยังแจ้งเตือนว่ากำลังละเว้นค่า destkeypass? ไม่มีเทคนิคอื่นใดที่จะใช้ได้ผล การใช้พรอมต์ไม่ได้ผลใช้ได้เฉพาะจากอาร์กิวเมนต์บรรทัดคำสั่ง ต้องเป็นจุดบกพร่องในการส่งออก PKCS12 ใครสามารถแสดงความคิดเห็น?
cmcginty

4
"openssl pkcs12 -in foo.p12 -out foo.pem" แสดงข้อผิดพลาดต่อไปนี้ป้อนรหัสผ่านนำเข้า: MAC ตรวจสอบแล้วว่าตกลงข้อผิดพลาดในการส่งออกคีย์และใบรับรอง 139848775526048: ข้อผิดพลาด: 06065064: กิจวัตรซองจดหมายดิจิทัล: EVP_DecryptFinal_ex: ถอดรหัสไม่ดี: evp_enc.c: 539 : 139848775526048: ข้อผิดพลาด: 23077074: PKCS12 รูทีน: PKCS12_pbe_crypt: pkcs12 cipherfinal error: p12_decr.c: 104: 139848775526048: ข้อผิดพลาด: 2306A075: PKCS12 รูทีน: PKCS12_pbe_crypt: pkcs12 ข้อผิดพลาด cipherfinal: p12_decr.c: 104: 139848775526048: ข้อผิดพลาด: 2306A075: รูทีน PKCS12: PKCS12_item_decrypt_d2 ข้อผิดพลาด วิธีแก้ปัญหานี้คืออะไร?
Udara SS Liyanage

1
คำเตือนสำหรับคนอื่นคำสั่ง keytool ใช้เวลาสักครู่ในการดำเนินการด้วยเหตุผลบางประการฉันต้องรอ 30 วินาทีจนกว่าการส่งออกจะเสร็จสิ้น
Nicolas Mommaerts

1
@ UdaraS.SLiyanage: ดูคำตอบของ Casey สำหรับวิธีแก้ปัญหา
Nicolas Mommaerts

29

ฉันได้รับข้อผิดพลาดopensslเมื่อใช้คำสั่งของ StoBor:

MAC verified OK
Error outputting keys and certificates
139940235364168:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:535:
139940235364168:error:23077074:PKCS12 routines:PKCS12_pbe_crypt:pkcs12 cipherfinal error:p12_decr.c:97:
139940235364168:error:2306A075:PKCS12 routines:PKCS12_item_decrypt_d2i:pkcs12 pbe crypt error:p12_decr.c:123:

ด้วยเหตุผลบางประการคำสั่งรูปแบบนี้เท่านั้นที่ใช้ได้กับไฟล์ JKS ของฉัน

keytool -importkeystore -srckeystore foo.jks \
   -destkeystore foo.p12 \
   -srcstoretype jks \
   -srcalias mykey \
   -deststoretype pkcs12 \
   -destkeypass DUMMY123

คีย์คือการตั้งdestkeypassค่าค่าของอาร์กิวเมนต์ไม่สำคัญ


6
ดูเหตุผลได้ที่นี่: herongyang.com/PKI/… Destkeypass DOES matter btw
Nicolas Mommaerts

ฉันเพิ่มคะแนนความคิดเห็นนี้ แต่ก็สมควรได้รับการโพสต์ มันยากที่จะหาที่นี่
Richie Rich

15

keytoolคำสั่งจะไม่ช่วยให้คุณสามารถส่งออกคีย์ส่วนตัวจากร้านค้าที่สำคัญ คุณต้องเขียนโค้ด Java เพื่อทำสิ่งนี้ เปิดที่เก็บคีย์รับคีย์ที่คุณต้องการและบันทึกลงในไฟล์ในรูปแบบ PKCS # 8 บันทึกใบรับรองที่เกี่ยวข้องด้วย

KeyStore ks = KeyStore.getInstance("jks");
/* Load the key store. */
...
char[] password = ...;
/* Save the private key. */
FileOutputStream kos = new FileOutputStream("tmpkey.der");
Key pvt = ks.getKey("your_alias", password);
kos.write(pvt.getEncoded());
kos.flush();
kos.close();
/* Save the certificate. */
FileOutputStream cos = new FileOutputStream("tmpcert.der");
Certificate pub = ks.getCertificate("your_alias");
cos.write(pub.getEncoded());
cos.flush();
cos.close();

ใช้ยูทิลิตี้ OpenSSL เพื่อแปลงไฟล์เหล่านี้ (ซึ่งอยู่ในรูปแบบไบนารี) เป็นรูปแบบ PEM

openssl pkcs8 -inform der -nocrypt < tmpkey.der > tmpkey.pem
openssl x509 -inform der < tmpcert.der > tmpcert.pem

ขอบคุณ erickson .. บทสรุปคือ "เราไม่สามารถทำการแปลงโดยตรงจาก JKS เป็น PEM ได้โดยใช้เพียงแค่ keytool และ openssl ยูทิลิตี้" ฉันถูกไหม?
Chathuranga Chandrasekara

4
คุณต้องเขียนโค้ดถึง Java 1.4 เท่านั้น - ตั้งแต่ Java 5 เป็นต้นไปสามารถรวม keytool และ openssl เพื่อทำการแปลงสองขั้นตอนจาก JKS -> PKCS # 12 -> PEM อย่างไรก็ตามการเขียนเครื่องมือหลักของคุณเองเป็นวิธีเดียวที่จะดำเนินการแปลงโดยตรงจาก JKS -> PEM
Stobor

ฉันคิดว่าตั้งแต่ JDK 6 เป็นต้นไป แต่ใช่ตอนนี้รองรับการนำเข้า PKCS # 12 แล้ว
erickson

15

การแปลงโดยตรงจากไฟล์ jks เป็น pem โดยใช้ keytool

keytool -exportcert -alias selfsigned -keypass password -keystore test-user.jks -rfc -file test-user.pem

10
ใช่ที่ส่งออกใบรับรอง อย่างไรก็ตามจะไม่ส่งออกข้อมูลสำคัญ ...
Stobor

นี่คือคำตอบง่ายๆที่แน่นอนสำหรับสิ่งที่ฉันค้นหาในหลายสิบเพจkeytoolและjbossเอกสารที่ไม่ประสบความสำเร็จ ขอบคุณ!
kratenko

15
สิ่งนี้ไม่ส่งออกข้อมูลสำคัญส่วนบุคคล
เจมส์

1
สิ่งนี้ส่งออกใบรับรองคีย์สาธารณะ
asami

ฉันพยายามเรียกใช้คำสั่งนี้ ต้องใช้รหัสผ่านป้อนรหัสผ่านที่เก็บคีย์: ข้อผิดพลาด keytool: java.io.IOException: ที่เก็บคีย์ถูกดัดแปลงหรือรหัสผ่านไม่ถูกต้อง ฉันใช้รหัสผ่านเป็น (รหัสผ่าน) แต่มีข้อผิดพลาดเดียวกัน
Mohit Singh

9

คำแนะนำแบบง่ายในการแปลงไฟล์ JKS เป็นรูปแบบ PEM และ KEY (.crt & .key):

keytool -importkeystore -srckeystore <Source-Java-Key-Store-File> -destkeystore <Destination-Pkcs12-File> -srcstoretype jks -deststoretype pkcs12 -destkeypass <Destination-Key-Password>

openssl pkcs12 -in <Destination-Pkcs12-File> -out <Destination-Pem-File>

openssl x509 -outform der -in <Destination-Pem-File> -out <Destination-Crt-File>

openssl rsa -in <Destination-Pem-File> -out <Destination-Key-File>


2

การแปลง JKS KeyStore เป็นไฟล์ PEM ไฟล์เดียวสามารถทำได้อย่างง่ายดายโดยใช้คำสั่งต่อไปนี้:

keytool -list -rfc -keystore "myKeystore.jks" | sed -e "/-*BEGIN [A-Z]*-*/,/-*END [A-Z]-*/!d" >> "myKeystore.pem"

คำอธิบาย:

  1. keytool -list -rfc -keystore "myKeystore.jks"แสดงรายการทุกอย่างใน KeyStore 'myKeyStore.jks' ในรูปแบบ PEM อย่างไรก็ตามยังพิมพ์ข้อมูลเพิ่มเติม
  2. | sed -e "/-*BEGIN [A-Z]*-*/,/-*END [A-Z]-*/!d"กรองทุกสิ่งที่เราไม่ต้องการ เราจะเหลือเพียง PEM ของทุกอย่างใน KeyStore
  3. >> "myKeystore.pem" เขียน PEM ลงในไฟล์ 'myKeyStore.pem'

3
bash
:!

1
@ user3217883 คุณสามารถลองsed "s/^\-*BEGIN [A-Z]*\-*$//g;s/^\-*END [A-Z]*\-*$//g"ใช้แทนได้ (ด้วย gnu sed) แต่ฉันไม่แน่ใจว่าเพียงพอหรือไม่หากมีใบรับรองมากกว่าหนึ่งรายการในที่เก็บคีย์ของคุณ
Idriss Neumann

ถ้าคุณได้รับbash: !d": event not found: สำหรับ bash เครื่องหมายอัศเจรีย์เป็นปุ่มสั้น ๆ ในการใช้คำสั่ง ในการใช้คำตอบนี้คุณต้องใช้เครื่องหมายวรรคตอนแทนเครื่องหมายคำพูดสำหรับตัวเลือกที่ใช้เป็น -e สำหรับ sedkeytool -list -rfc -keystore "myKeystore.jks" | sed -e '/-*BEGIN [A-Z]*-*/,/-*END [A-Z]-*/!d' >> "myKeystore.pem"
B.Adler

น่าเสียดายที่นี่เป็นการส่งออกใบรับรองเท่านั้นไม่ใช่คีย์ส่วนตัว
Maddin

2

ก่อนอื่นให้ดัมพ์ที่เก็บคีย์จาก JKS ไปยัง PKCS12

1. keytool -importkeystore -srckeystore ~ ​​/ .android / debug.keystore -destkeystore intermediate.p12 -srcstoretype JKS -deststoretype PKCS12

ถ่ายโอนไฟล์ pkcs12 ใหม่ลงใน pem

  1. openssl pkcs12 -in intermediate.p12 -nodes -out intermediate.rsa.pem

คุณควรมีทั้งใบรับรองและคีย์ส่วนตัวในรูปแบบ pem แยกพวกเขาออก ใส่ส่วนระหว่าง“ BEGIN CERTIFICATE” และ“ END CERTIFICATE” ลงใน cert.x509.pem ใส่ส่วนระหว่าง“ BEGIN RSA PRIVATE KEY” และ“ END RSA PRIVATE KEY” เป็น private.rsa.pem แปลงคีย์ส่วนตัวเป็นรูปแบบ pk8 เป็น คาดหวังโดย signapk

3. openssl pkcs8 -topk8 -outform DER -in private.rsa.pem -inform PEM -out private.pk8 -nocrypt


1

ดีOpenSSL ควรจะทำมันอย่างคล่องแคล่วจากไฟล์ # 12:

openssl pkcs12 -in pkcs-12-certificate-file -out pem-certificate-file
openssl pkcs12 -in pkcs-12-certificate-and-key-file -out pem-certificate-and-key-file

อาจมีรายละเอียดเพิ่มเติมว่าข้อผิดพลาด / ความล้มเหลวคืออะไร


1

ในกรณีที่คุณไม่ได้ติดตั้ง openssl และคุณกำลังมองหาวิธีแก้ปัญหาอย่างรวดเร็วมีซอฟต์แวร์ที่เรียกว่าportcleซึ่งมีประโยชน์มากและมีขนาดเล็กในการดาวน์โหลด

ข้อเสียคือไม่มี command line เท่าที่ฉันรู้ แต่จาก GUI การส่งออกคีย์ส่วนตัว PEM ค่อนข้างตรงไปตรงมา:

  1. เปิดร้านกุญแจ JKS
  2. คลิกขวาที่รายการคีย์ส่วนตัวของคุณแล้วเลือกส่งออก
  3. เลือกคีย์ส่วนตัวและใบรับรองและรูปแบบ PEM

    ส่งออกคีย์ส่วนตัว PEM จาก JKS ด้วย Portcle



0

ก่อนอื่นให้สร้างไฟล์ที่เก็บคีย์เป็น

C: \ Program Files \ Android \ Android Studio \ jre \ bin> keytool -keystore androidkey.jks -genkeypair -alias androidkey

ป้อนรหัสผ่านที่เก็บคีย์:
ป้อนรหัสผ่านใหม่อีกครั้ง:
ชื่อและนามสกุลของคุณคืออะไร? Unknown: FirstName LastName
หน่วยองค์กรของคุณชื่ออะไร Unknown: Mobile Development
ชื่อองค์กรของคุณคืออะไร? ไม่ทราบ: ชื่อ บริษัท ของคุณชื่อ
เมืองหรือพื้นที่ของคุณคืออะไร? รัฐหรือจังหวัดของคุณชื่ออะไร?
รหัสประเทศสองตัวอักษรสำหรับหน่วยนี้คืออะไร? Unknown: IN // กด Enter

ตอนนี้มันจะขอให้ยืนยัน

CN = FirstName LastName, OU = Mobile Development, O = ชื่อ บริษัท ของคุณ, L = CityName, ST = StateName, C = IN ถูกต้องหรือไม่ [ไม่]: ใช่

ป้อนรหัสผ่านคีย์สำหรับ (ส่งคืนหากเหมือนกับรหัสผ่านที่เก็บคีย์): กด Enter หากคุณต้องการรหัสผ่านเดียวกัน

สร้างคีย์แล้วตอนนี้คุณสามารถรับไฟล์ pem โดยใช้คำสั่งต่อไปนี้

C: \ Program Files \ Android \ Android Studio \ jre \ bin> keytool -export -rfc -alias androidkey -file android_certificate.pem -keystore androidkey.jks
ป้อนรหัสผ่านที่
เก็บคีย์: ใบรับรองที่เก็บไว้ในไฟล์


0

การแปลง Java Keystore เป็นรูปแบบ PEM

คำตอบที่แม่นยำที่สุดของทั้งหมดต้องเป็นไปไม่ได้

ที่เก็บคีย์ Java เป็นเพียงอุปกรณ์จัดเก็บสำหรับคีย์การเข้ารหัสและใบรับรองในขณะที่ PEM เป็นรูปแบบไฟล์สำหรับใบรับรอง X.509 เท่านั้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.