2008-09-29 32 views

Trả lời

30

Một phần của mã ban đầu từ Ví dụ Depot niêm yết tất cả các bí danh trong một cửa hàng chính:

// Load input stream into keystore 
    keystore.load(is, password.toCharArray()); 

    // List the aliases 
    Enumeration aliases = keystore.aliases(); 
    for (; aliases.hasMoreElements();) { 
     String alias = (String)aliases.nextElement(); 

     // Does alias refer to a private key? 
     boolean b = keystore.isKeyEntry(alias); 

     // Does alias refer to a trusted certificate? 
     b = keystore.isCertificateEntry(alias); 
    } 

Các xuất khẩu các phím tin đã đưa trên Sun forums một vài tháng trước đây, và u:turingcompleter đã đưa ra với một lớp DumpPrivateKey để ghép vào ứng dụng của bạn.

Lưu ý: sử dụng gói Sun, which is a "bad thing".
Nếu bạn có thể tải apache commons code, đây là một phiên bản mà sẽ biên dịch mà không cần cảnh báo:

javac -classpath .:commons-codec-1.4/commons-codec-1.4.jar DumpPrivateKey.java 

và sẽ cho kết quả tương tự:

import java.io.FileInputStream; 
import java.security.Key; 
import java.security.KeyStore; 
//import sun.misc.BASE64Encoder; 
import org.apache.commons.codec.binary.Base64; 

public class DumpPrivateKey { 
    /** 
    * Provides the missing functionality of keytool 
    * that Apache needs for SSLCertificateKeyFile. 
    * 
    * @param args <ul> 
    *    <li> [0] Keystore filename. 
    *    <li> [1] Keystore password. 
    *    <li> [2] alias 
    *    </ul> 
    */ 
    static public void main(String[] args) 
    throws Exception { 
     if(args.length < 3) { 
      throw new IllegalArgumentException("expected args: Keystore filename, Keystore password, alias, <key password: default same tha 
n keystore"); 
     } 
     final String keystoreName = args[0]; 
     final String keystorePassword = args[1]; 
     final String alias = args[2]; 
     final String keyPassword = getKeyPassword(args,keystorePassword); 
     KeyStore ks = KeyStore.getInstance("jks"); 
     ks.load(new FileInputStream(keystoreName), keystorePassword.toCharArray()); 
     Key key = ks.getKey(alias, keyPassword.toCharArray()); 
     //String b64 = new BASE64Encoder().encode(key.getEncoded()); 
     String b64 = new String(Base64.encodeBase64(key.getEncoded(),true)); 
     System.out.println("-----BEGIN PRIVATE KEY-----"); 
     System.out.println(b64); 
     System.out.println("-----END PRIVATE KEY-----"); 
    } 
    private static String getKeyPassword(final String[] args, final String keystorePassword) 
    { 
     String keyPassword = keystorePassword; // default case 
     if(args.length == 4) { 
     keyPassword = args[3]; 
     } 
     return keyPassword; 
    } 
} 

Bạn có thể sử dụng nó như vậy:

java -classpath .:commons-codec-1.4/commons-codec-1.4.jar DumpPrivateKey $HOME/.keystore changeit tomcat 
+0

Điều này hiệu quả. Tôi đã có một khách hàng đã tạo ra một yêu cầu chứng chỉ bằng cách sử dụng các hướng dẫn tomcat, vì vậy khóa riêng đã được cài đặt trong kho khóa của họ. Tôi cần nó để làm việc với apache. – ScArcher2

+1

Một năm sau và bạn đã giải quyết được vấn đề của người khác (ví dụ: của tôi). Làm tốt lắm! :) –

+0

Thực ra, Điều này sẽ được cập nhật với thông số bổ sung: [3] Mật khẩu khóa và dòng 'Khóa phím = ks.getKey (args [2], args [1]. ToCharArray());' nên đọc ' Key key = ks.getKey (args [2], args [3] .toCharArray()); '. Mã ban đầu giả định rằng mật khẩu KEY giống với mật khẩu KEYSTORE, khi chúng không nhất thiết phải giống nhau. – REW

3

Trước hết, hãy cẩn thận! Tất cả bảo mật của bạn phụ thuộc vào & hellip; er & hellip; riêng tư trong số khóa riêng tư của bạn. Keytool không có tích hợp xuất khẩu chính để tránh tình cờ tiết lộ tài liệu nhạy cảm này, vì vậy bạn có thể muốn xem xét một số biện pháp bảo vệ bổ sung có thể được áp dụng để bảo vệ các khóa đã xuất của bạn.

Dưới đây là một số mã đơn giản mà mang đến cho bạn không được mã hóa PKCS # 8 PrivateKeyInfo có thể được sử dụng bởi OpenSSL (xem -nocrypt tùy chọn pkcs8 utility của nó):

KeyStore keys = ... 
char[] password = ... 
Enumeration<String> aliases = keys.aliases(); 
while (aliases.hasMoreElements()) { 
    String alias = aliases.nextElement(); 
    if (!keys.isKeyEntry(alias)) 
    continue; 
    Key key = keys.getKey(alias, password); 
    if ((key instanceof PrivateKey) && "PKCS#8".equals(key.getFormat())) { 
    /* Most PrivateKeys use this format, but check for safety. */ 
    try (FileOutputStream os = new FileOutputStream(alias + ".key")) { 
     os.write(key.getEncoded()); 
     os.flush(); 
    } 
    } 
} 

Nếu bạn cần định dạng khác, bạn có thể sử dụng một KeyFactory để lấy thông số khóa minh bạch cho các loại khóa khác nhau. Sau đó, bạn có thể lấy, ví dụ, số mũ riêng của khóa riêng RSA và xuất nó theo định dạng mong muốn của bạn. Điều đó sẽ làm cho một chủ đề tốt cho một câu hỏi tiếp theo.

6

Nếu bạn không cần làm điều đó theo chương trình, nhưng chỉ muốn quản lý khóa của bạn, thì tôi đã sử dụng công cụ KeyMan miễn phí của IBM trong một thời gian dài. Rất tốt cho việc xuất một khóa riêng sang một tệp PFX (sau đó bạn có thể dễ dàng sử dụng OpenSSL để thao tác nó, trích xuất nó, thay đổi pwds, v.v.).

https://www.ibm.com/developerworks/mydeveloperworks/groups/service/html/communityview?communityUuid=6fb00498-f6ea-4f65-bf0c-adc5bd0c5fcc

Chọn keystore của bạn, chọn mục khóa riêng, sau đó File-> Save vào một tập tin pkcs12 (* pfx, điển hình). Sau đó bạn có thể xem nội dung với:

$ openssl pkcs12 -in mykeyfile.pfx -info

+1

Liên kết trang KeyMan đã thay đổi thành https://www.ibm.com/developerworks/mydeveloperworks/groups/service/html/communityview?communityUuid=6fb00498-f6ea-4f65-bf0c-adc5bd0c5fcc (không bao giờ kết thúc url 404/rewritings!) – manikanta

+0

Liên kết tải xuống nằm ở góc trên cùng bên phải của trang. Bạn sẽ cần một ID IBM ... bạn có thể tạo một tài khoản miễn phí. Tôi đã chọn tải xuống tùy chọn zip đầu tiên. Để làm cho nó hoạt động trên Windows, bạn cần phải giải nén vào C: \ Program Files \ IBM \ BlueZ \ KeyMan, hoặc bạn cần giải nén bất cứ nơi nào bạn muốn và thay đổi dòng đầu tiên của km.bat để có đường dẫn đến thư mục chứa km.bat. Sau đó, chỉ cần chạy km.bat mà không có bất kỳ đối số. Nên làm việc miễn là java là trên con đường của bạn. – ArtOfWarfare

102

Bạn có thể trích xuất một khóa bí mật từ một keystore với Java6 và OpenSSL. Tất cả điều này phụ thuộc vào thực tế là cả Java và OpenSSL đều hỗ trợ các keystores được định dạng PKCS # 12. Để thực hiện việc trích xuất, trước tiên bạn sử dụng keytool để chuyển đổi sang định dạng chuẩn. Đảm bảo rằng bạn sử dụng cùng một mật khẩu cho cả hai tệp (mật khẩu khóa riêng tư, không phải mật khẩu kho khóa) hoặc bạn sẽ gặp lỗi sau này trong bước thứ hai.

keytool -importkeystore -srckeystore keystore.jks \ 
    -destkeystore intermediate.p12 -deststoretype PKCS12 

Tiếp theo, sử dụng OpenSSL để làm việc khai thác để PEM:

openssl pkcs12 -in intermediate.p12 -out extracted.pem -nodes 

Bạn sẽ có thể xử lý các tập tin một cách dễ dàng PEM đủ; đó là văn bản thuần túy với khóa cá nhân không mã hóa được mã hóa và chứng chỉ (s) bên trong nó (ở định dạng khá rõ ràng).

Khi bạn thực hiện việc này, hãy cẩn thận để giữ cho tệp được tạo an toàn. Chúng chứa thông tin bí mật. Không có gì sẽ cảnh báo bạn nếu bạn không bảo mật chúng một cách chính xác. Phương pháp dễ nhất để bảo vệ chúng là thực hiện tất cả điều này trong một thư mục không có bất kỳ quyền truy cập nào cho bất kỳ ai khác ngoài người dùng. Và không bao giờ đặt mật khẩu của bạn trên dòng lệnh hoặc trong các biến môi trường; quá dễ dàng để người dùng khác nắm bắt.

+2

Câu chuyện sau: Cần thiết này ngày hôm nay để chúng tôi có thể đặt wireshark giữa một máy khách Java webservice và một máy chủ webservice Java; nó hoạt động như một giấc mơ và chúng tôi sửa lỗi của chúng tôi (một vấn đề cấu hình trong xử lý cookie). Tôi nghĩ rằng tôi muốn chia sẻ vì nó là thuận tiện để không phải viết bất kỳ mã để làm điều này loại, và nhiều người sẽ có các công cụ cần thiết được cài đặt, không giống như với các câu trả lời khác. –

+0

Bài đăng tuyệt vời. Làm tốt lắm thưa ngài! –

+1

thankyou thankyou thankyou !!! –

4

Đối với phát triển android, để chuyển đổi keystore được tạo ra trong nhật thực ADT vào khóa công khai và khóa bí mật được sử dụng trong SignApk.jar:

xuất khẩu chủ lực riêng:

keytool.exe -importkeystore -srcstoretype JKS -srckeystore my-release-key.keystore -deststoretype PKCS12 -destkeystore keys.pk12.der 
openssl.exe pkcs12 -in keys.pk12.der -nodes -out private.rsa.pem 

chỉnh sửa private.rsa.pem và rời "----- BEGIN PRIVATE kEY -----" thành "----- END PRIVATE kEY -----" đoạn văn, sau đó:

openssl.exe base64 -d -in private.rsa.pem -out private.rsa.der 

xuất khẩu chủ lực công cộng:

keytool.exe -exportcert -keystore my-release-key.keystore -storepass <KEYSTORE_PASSWORD> -alias alias_name -file public.x509.der 

dấu apk:

java -jar SignApk.jar public.x509.der private.rsa.der input.apk output.apk 
+0

Tôi đã thử đề xuất của bạn tuy nhiên nó không thành công ở lệnh openssl đầu tiên - nó báo cáo lỗi giải mã. Keystore ban đầu mà tôi đã thử nghiệm là các thường trình được sử dụng với jarsigner. Sự thất bại xảy ra cả dưới các công cụ của Cygwin, cũng như các công cụ của Fedora. – mah

+0

Nó làm việc cho tôi, tôi đã tìm kiếm trên toàn bộ web cho giải pháp này, cảm ơn chủ nghĩa tự làm –

5

Đây là một phiên bản ngắn hơn của mã ở trên, trong Groovy. Ngoài ra còn có mã hóa base64 cài sẵn:

import java.security.Key 
import java.security.KeyStore 

if (args.length < 3) 
     throw new IllegalArgumentException('Expected args: <Keystore file> <Keystore format> <Keystore password> <alias> <key password>') 

def keystoreName = args[0] 
def keystoreFormat = args[1] 
def keystorePassword = args[2] 
def alias = args[3] 
def keyPassword = args[4] 

def keystore = KeyStore.getInstance(keystoreFormat) 
keystore.load(new FileInputStream(keystoreName), keystorePassword.toCharArray()) 
def key = keystore.getKey(alias, keyPassword.toCharArray()) 

println "-----BEGIN PRIVATE KEY-----" 
println key.getEncoded().encodeBase64() 
println "-----END PRIVATE KEY-----" 
0

Một cách khác ít dễ dàng hơn nhưng dễ hiểu hơn là thực hiện với JXplorer. Mặc dù công cụ này được thiết kế để duyệt qua các thư mục LDAP, nhưng nó có giao diện đồ họa dễ sử dụng để thao tác các keystores. Một chức năng như vậy trên GUI có thể xuất các khóa riêng từ một kho khóa JKS.

Các vấn đề liên quan