दिलचस्प पोस्ट
एंड्रॉयड। कैसे डेटासेट चंचल () विधि और ListViews काम को सूचित नहीं करता है? सी # 32/64 बिट, या किसी भी सीपीयू के लिए संकलन? फ़ायरफ़ॉक्स समर्थन की स्थिति है: टेबल तत्वों पर रिश्तेदार? पेस्ट में NAs को दबाएं () कंसोल.लॉग को प्रत्येक फ़ंक्शन पर स्वचालित रूप से जोड़ना सेलेनियम में पेज लोड की प्रतीक्षा करें GET अनुरोध में समान पैरामीटर नाम के लिए एकाधिक मानों को पारित करने का सही तरीका आप कैसे सी # में कोड के साथ नेटवर्क सेटिंग्स (आईपी पता, डीएनएस, WINS, होस्ट नाम) बदल सकते हैं एल्गोरिथ्म यह जानने के लिए कि किसी निश्चित संख्या तक एक सूची में कितनी संख्या है इकाई विशेषता मूल्य डाटाबेस बनाम सख्त संबंधपरक मॉडल ईकॉमर्स 'करीइंग' क्या है? 2 डी विमान पर एन बिंदु को देखते हुए, एक ही सीधी रेखा पर मौजूद अंकों की अधिकतम संख्या पाएं एंड्रॉइड एसडीके 22 – सर्चव्यू रेंडरिंग समस्याएं डाटा ट्रांसफर ऑब्जेक्ट क्या है? सूची से अद्वितीय आइटम प्राप्त करना

PEM BASE64 एन्कोडेड निजी कुंजी फ़ाइल से आरएसए निजी कुंजी प्राप्त करना

मेरे पास एक निजी कुंजी फ़ाइल है (पीईएम बेस 64 एन्कोडेड)। मैं इसका इस्तेमाल करना चाहता हूं और कुछ अन्य डेटा को डिक्रिप्ट करने के लिए करना चाहता हूं। जावा का उपयोग करके मैंने फाइल पढ़ने और इसमें BASE64 एन्कोडेड डेटा को डीकोड करने की कोशिश की … यह कोड स्निपेट है जो मैंने कोशिश की है ….

import java.io.*; import java.nio.ByteBuffer; import java.security.*; import java.security.spec.PKCS8EncodedKeySpec; import com.ibm.crypto.fips.provider.RSAPrivateKey; import com.ibm.misc.BASE64Decoder; public class GetPrivateKey { public static RSAPrivateKey get() throws Exception { File privateKeyFile = new File("privatekey.key"); byte[] encodedKey = new byte[(int) privateKeyFile.length()]; new FileInputStream(privateKeyFile).read(encodedKey); ByteBuffer keyBytes = new BASE64Decoder().decodeBufferToByteBuffer(encodedKey.toString()); PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(keyBytes.array()); KeyFactory kf = KeyFactory.getInstance("RSA", "IBMJCEFIPS"); RSAPrivateKey pk = (RSAPrivateKey) kf.generatePrivate(privateKeySpec); return pk; } public static void main(String[] args) throws Exception { PrivateKey privKey = FormatMePlease.get(); System.out.println(privKey.toString()); } } 

मुझे निम्नलिखित त्रुटियां मिल रही हैं I

 Exception in thread "main" java.security.spec.InvalidKeySpecException: Inappropriate key specification: DerInputStream.getLength(): lengthTag=127, too big. at com.ibm.crypto.fips.provider.RSAKeyFactory.b(Unknown Source) at com.ibm.crypto.fips.provider.RSAKeyFactory.engineGeneratePrivate(Unknown Source) at java.security.KeyFactory.generatePrivate(Unknown Source) at GetPrivateKey.get(GetPrivateKey.java:24) at GetPrivateKey.main(GetPrivateKey.java:29) 

फ़ाइल "privatekey.key" की सामग्री

 -----BEGIN RSA PRIVATE KEY----- MIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAF53wUbKmDHtvfOb8u1HPqEBFNNF csnOMjIcSEhAwIQMbgrOuQ+vH/YgXuuDJaURS85H8P4UTt6lYOJn+SFnXvS82E7LHJpVrWwQzbh2 QKh13/akPe90DlNTUGEYO7rHaPLqTlld0jkLFSytwqfwqn9yrYpM1ncUOpCciK5j8t8MzO71LJoJ g24CFxpjIS0tBrJvKzrRNcxWSRDLmu2kNmtsh7yyJouE6XoizVmBmNVltHhFaDMmqjugMQA2CZfL rxiR1ep8TH8IBvPqysqZI1RIpB/e0engP4/1KLrOt+6gGS0JEDh1kG2fJObl+N4n3sCOtgaz5Uz8 8jpwbmZ3Se8CAwEAAQKCAQAdOsSs2MbavAsIM3qo/GBehO0iqdxooMpbQvECmjZ3JTlvUqNkPPWQ vFdiW8PsHTvtackhdLsqnNUreKxXL5rr8vqi9qm0/0mXpGNi7gP3m/FeaVdYnfpIwgCe6lag5k6M yv7PG/6N8+XrWyBdwlOe96bGohvB4Jp2YFjSTM67QONQ8CdmfqokqJ8/3RyrpDvGN3iX3yzBqXGO jPkoJQv3I4lsYdR0nl4obHHnMSeWCQCYvJoZ7ZOliu/Dd0ksItlodG6s8r/ujkSa8VIhe0fnXTf0 i7lqa55CAByGN4MOR0bAkJwIB7nZzQKurBPcTAYJFFvAc5hgMnWT0XW83TehAoGBALVPGnznScUw O50OXKI5yhxGf/XDT8g28L8Oc4bctRzI+8YfIFfLJ57uDGuojO/BpqtYmXmgORru0jYR8idEkZrx gf62czOiJrCWTkBCEMtrNfFHQJQCQrjfbHofp7ODnEHbHFm7zdlbfNnEBBaKXxd2rVv4UTEhgftv wsHcimbXAoGBAIViWrHWElMeQT0datqlThE/u51mcK4VlV7iRWXVa1/gAP85ZAu44VvvDlkpYVkF zSRR+lHSOzsubDMN45OBQW6UA3RPg4TCvrTOmhQUeF5XPuSdcD0R2At6pdaLwAKnOtILg13Ha6ym Igjv8glodvem3hWLmpHIhNBiaXtf8wqpAoGADH5a8OhvKOtd8EChGXyp9LDW+HRw9vbyN/gi9dQX ltgyoUBb1jDllgoJSRHgRFUvyvbb/ImR5c03JwqtiQ8siWTC9G5WGeS+jcSNt9fVmG7W1L14MbrG Jj8fFns/7xrOlasnlPdgA+5N+CONtI/sZY2D/KZr0drhPhZBcWJlFxkCgYAn+4SOPEo/6hjKNhA6 vER7fSxDEVsDg+rDh3YgAWpvUdlaqBxqOyAqi600YugQZGHK2lv7vNYOdmrunuIx7BPuDqY+bjtR R4Mc9bVQAZbXSLXMl7j2RWwKfNhLSJbk9LX4EoVtTgLjvOUE4tAdq9fFgpqdwLwzqPTO9kECP4++ CQKBgH6tO/xcNxG/uXUideluAn3H2KeyyznZMJ7oCvzf26/XpTAMI243OoeftiKVMgxuZ7hjwqfn /VHXABc4i5gchr9RzSb1hZ/IqFzq2YGmbppg5Ok2cgwalDoDBi21bRf8aDRweL62mO+7aPnCQZ58 j5W72PB8BAr6xg0Oro25O4os -----END RSA PRIVATE KEY----- 

इसी प्रकार के प्रश्न यहां पोस्ट किए गए हैं, लेकिन मेरे लिए कोई फायदा नहीं हुआ। लगभग उन सभी ने Bouncycastle प्रदाता का उपयोग करने का सुझाव दिया है जो उपयोग करने के लिए तैयार नहीं है जैसा कि एक प्रदाता का उपयोग करने वाला है जो FIPS compliant है और मुझे यकीन नहीं है अगर BC प्रदाता FIPS compliant है

मुझे इससे बाहर निकलने में मदद की बहुत सराहना होगी … अग्रिम धन्यवाद।

वेब के समाधान से एकत्रित समाधान "PEM BASE64 एन्कोडेड निजी कुंजी फ़ाइल से आरएसए निजी कुंजी प्राप्त करना"

एएसएन 1 सुपरपोर्ट की कमी के कारण एंड्रॉइड पर पीकेसीएस 1 पार्सिंग (केवल पीकेसीएसओ फॉर्मेट ही बॉक्स पर काम करता है) की वजह से एंड्रॉइड पर एक थकाऊ काम हो गया है, लेकिन अगर आप डीआर इंटीजर्स को पढ़ने के लिए स्पोंजी कैसल जार शामिल करते हैं

 String privKeyPEM = key.replace( "-----BEGIN RSA PRIVATE KEY-----\n", "") .replace("-----END RSA PRIVATE KEY-----", ""); // Base64 decode the data byte[] encodedPrivateKey = Base64.decode(privKeyPEM, Base64.DEFAULT); try { ASN1Sequence primitive = (ASN1Sequence) ASN1Sequence .fromByteArray(encodedPrivateKey); Enumeration<?> e = primitive.getObjects(); BigInteger v = ((DERInteger) e.nextElement()).getValue(); int version = v.intValue(); if (version != 0 && version != 1) { throw new IllegalArgumentException("wrong version for RSA private key"); } /** * In fact only modulus and private exponent are in use. */ BigInteger modulus = ((DERInteger) e.nextElement()).getValue(); BigInteger publicExponent = ((DERInteger) e.nextElement()).getValue(); BigInteger privateExponent = ((DERInteger) e.nextElement()).getValue(); BigInteger prime1 = ((DERInteger) e.nextElement()).getValue(); BigInteger prime2 = ((DERInteger) e.nextElement()).getValue(); BigInteger exponent1 = ((DERInteger) e.nextElement()).getValue(); BigInteger exponent2 = ((DERInteger) e.nextElement()).getValue(); BigInteger coefficient = ((DERInteger) e.nextElement()).getValue(); RSAPrivateKeySpec spec = new RSAPrivateKeySpec(modulus, privateExponent); KeyFactory kf = KeyFactory.getInstance("RSA"); PrivateKey pk = kf.generatePrivate(spec); } catch (IOException e2) { throw new IllegalStateException(); } catch (NoSuchAlgorithmException e) { throw new IllegalStateException(e); } catch (InvalidKeySpecException e) { throw new IllegalStateException(e); } 

आपने अभी तक उस निजी कुंजी को प्रकाशित किया है, इसलिए अब पूरी दुनिया जानती है कि यह क्या है। उम्मीद है कि यह सिर्फ परीक्षण के लिए था।

संपादित करें: अन्य लोगों ने ध्यान दिया है कि प्रकाशित कुंजी के openssl पाठ शीर्षलेख, —– आरएसए निजी कुंजी —–, इंगित करता है कि यह पीकेसीएस # 1 है। हालांकि, सवाल में कुंजी की वास्तविक Base64 सामग्री PKCS # 8 है जाहिर है ओपी प्रतिलिपि और किसी अज्ञात कारण के लिए पीकेसीएस # 8 कुंजी पर पीकेसीएस # 1 कुंजी के हेडर और ट्रेलर चिपकाए गए। मैं नीचे दिया गया नमूना कोड PKCS # 8 निजी कुंजी के साथ काम करता है

यहां कुछ कोड है जो उस डेटा से निजी कुंजी बनाएगा। आपको अपने आईबीएम बेस 64 डीकोडर के साथ बेस 64 डीकोडिंग को बदलना होगा।

 public class RSAToy { private static final String BEGIN_RSA_PRIVATE_KEY = "-----BEGIN RSA PRIVATE KEY-----\n" + "MIIEuwIBADAN ...skipped the rest\n" // + ... // + ... skipped the rest // + ... + "-----END RSA PRIVATE KEY-----"; public static void main(String[] args) throws Exception { // Remove the first and last lines String privKeyPEM = BEGIN_RSA_PRIVATE_KEY.replace("-----BEGIN RSA PRIVATE KEY-----\n", ""); privKeyPEM = privKeyPEM.replace("-----END RSA PRIVATE KEY-----", ""); System.out.println(privKeyPEM); // Base64 decode the data byte [] encoded = Base64.decode(privKeyPEM); // PKCS8 decode the encoded RSA private key PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded); KeyFactory kf = KeyFactory.getInstance("RSA"); PrivateKey privKey = kf.generatePrivate(keySpec); // Display the results System.out.println(privKey); } } 

यह एक निजी कुंजी के PKCS # 1 प्रारूप है इस कोड को आज़माएं यह उछाल वाले कैसल या अन्य तृतीय-पक्ष क्रिप्टो प्रदाताओं का उपयोग नहीं करता है। बस जावा। सिक्योरिटी और सूर्य। डीईआर सैकस पार्सिंग के लिए सुरक्षा। इसके अलावा यह पीकेसीएस # 8 प्रारूप (पीईएम फ़ाइल में एक निजी कुंजी के पार्सिंग का समर्थन करता है जिसमें एक शीर्षलेख "—– प्राइवेट कुंजी —–") है।

 import sun.security.util.DerInputStream; import sun.security.util.DerValue; import java.io.File; import java.io.IOException; import java.math.BigInteger; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.security.GeneralSecurityException; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.RSAPrivateCrtKeySpec; import java.util.Base64; public static PrivateKey pemFileLoadPrivateKeyPkcs1OrPkcs8Encoded(File pemFileName) throws GeneralSecurityException, IOException { // PKCS#8 format final String PEM_PRIVATE_START = "-----BEGIN PRIVATE KEY-----"; final String PEM_PRIVATE_END = "-----END PRIVATE KEY-----"; // PKCS#1 format final String PEM_RSA_PRIVATE_START = "-----BEGIN RSA PRIVATE KEY-----"; final String PEM_RSA_PRIVATE_END = "-----END RSA PRIVATE KEY-----"; Path path = Paths.get(pemFileName.getAbsolutePath()); String privateKeyPem = new String(Files.readAllBytes(path)); if (privateKeyPem.indexOf(PEM_PRIVATE_START) != -1) { // PKCS#8 format privateKeyPem = privateKeyPem.replace(PEM_PRIVATE_START, "").replace(PEM_PRIVATE_END, ""); privateKeyPem = privateKeyPem.replaceAll("\\s", ""); byte[] pkcs8EncodedKey = Base64.getDecoder().decode(privateKeyPem); KeyFactory factory = KeyFactory.getInstance("RSA"); return factory.generatePrivate(new PKCS8EncodedKeySpec(pkcs8EncodedKey)); } else if (privateKeyPem.indexOf(PEM_RSA_PRIVATE_START) != -1) { // PKCS#1 format privateKeyPem = privateKeyPem.replace(PEM_RSA_PRIVATE_START, "").replace(PEM_RSA_PRIVATE_END, ""); privateKeyPem = privateKeyPem.replaceAll("\\s", ""); DerInputStream derReader = new DerInputStream(Base64.getDecoder().decode(privateKeyPem)); DerValue[] seq = derReader.getSequence(0); if (seq.length < 9) { throw new GeneralSecurityException("Could not parse a PKCS1 private key."); } // skip version seq[0]; BigInteger modulus = seq[1].getBigInteger(); BigInteger publicExp = seq[2].getBigInteger(); BigInteger privateExp = seq[3].getBigInteger(); BigInteger prime1 = seq[4].getBigInteger(); BigInteger prime2 = seq[5].getBigInteger(); BigInteger exp1 = seq[6].getBigInteger(); BigInteger exp2 = seq[7].getBigInteger(); BigInteger crtCoef = seq[8].getBigInteger(); RSAPrivateCrtKeySpec keySpec = new RSAPrivateCrtKeySpec(modulus, publicExp, privateExp, prime1, prime2, exp1, exp2, crtCoef); KeyFactory factory = KeyFactory.getInstance("RSA"); return factory.generatePrivate(keySpec); } throw new GeneralSecurityException("Not supported format of a private key"); } 

आपको सामना करने वाली समस्या यह है कि दो प्रकार की पीईएम प्रारूपित कुंजियां हैं: पीकेसीएस 8 और एसएसएलईई। यह मदद नहीं करता है कि ओपनएसएसएल कमांड के आधार पर दोनों का इस्तेमाल करता है:

सामान्य openssl genrsa कमांड एक SSLeay प्रारूप पीईएम उत्पन्न करेगा। पीएससीएसएएस फाइल से एक एक्सप्लस पीएलसीएस 12 फाइल में एक पीकेसीएसओ फाइल openssl pkcs12 -in file.p12 जाएगी।

पीकेसीएस 8 एन्कोडेडकेएसईपीई का इस्तेमाल करते हुए जावा में बाद में पीकेसीएसओ प्रारूप को मूल रूप से खोला जा सकता है। SSLeay स्वरूपित कुंजियां, दूसरी ओर, मूल रूप से खोला नहीं जा सकता।

SSLeay निजी कुंजियों को खोलने के लिए, आप या तो बाउंसी कैस्टल प्रदाता का उपयोग कर सकते हैं, जैसे कि पहले या नहीं-अभी-कम-कॉमन्स- SSL ने BouncyCastle से कम से कम आवश्यक कोड को उधार लिया है PKCS8 और पीईएम और डीईआर प्रारूप में SSLeay कुंजी को पार्स करने के लिए: http: //juliusdavies.ca/commons-ssl/pkcs8.html (मुझे यकीन नहीं है कि यदि नहीं-अभी-कॉमन्स-एसएलएल FIPS संगत होगा)

मुख्य स्वरूप पहचान

OpenSSL मैन पेजों के निष्कर्ष से, दो प्रारूपों के लिए प्रमुख शीर्षलेख निम्नानुसार हैं:

पीकेसीएस 8 प्रारूप

गैर-एन्क्रिप्टेड: -----BEGIN PRIVATE KEY-----
एन्क्रिप्ट किया गया: -----BEGIN ENCRYPTED PRIVATE KEY-----

SSLeay प्रारूप

-----BEGIN RSA PRIVATE KEY-----

(ये अन्य जवाबों के प्रति विरोधाभासी हैं, लेकिन मैंने PKCS8EncodedKeySpec द्वारा ओपनएसएसएल के आउटपुट का परीक्षण किया है। केवल पीकेसीएस 8 कुंजियाँ, दिखा रहा है ----BEGIN PRIVATE KEY----- नेटिव रूप से काम करें)

जैसा कि अन्य लोगों ने प्रतिक्रिया दी है, आप जिस कुंजी को पार्स करने की कोशिश कर रहे हैं, उसमें उचित PKCS # 8 हेडर नहीं है, जो कि ओरेकल के PKCS8EncodedKeySpec 8 PKCS8EncodedKeySpec को इसे समझने की जरूरत है। यदि आप कुंजी को कन्वर्ट करने के लिए openssl pkcs8 का उपयोग नहीं करना चाहते हैं या इसे openssl pkcs8 आंतरिक एपीआई का उपयोग करके पार्स करना चाहते हैं तो आप openssl pkcs8 # 8 हेडर को इस तरह openssl pkcs8 सकते हैं:

 static final Base64.Decoder DECODER = Base64.getMimeDecoder(); private static byte[] buildPKCS8Key(File privateKey) throws IOException { final String s = new String(Files.readAllBytes(privateKey.toPath())); if (s.contains("--BEGIN PRIVATE KEY--")) { return DECODER.decode(s.replaceAll("-----\\w+ PRIVATE KEY-----", "")); } if (!s.contains("--BEGIN RSA PRIVATE KEY--")) { throw new RuntimeException("Invalid cert format: "+ s); } final byte[] innerKey = DECODER.decode(s.replaceAll("-----\\w+ RSA PRIVATE KEY-----", "")); final byte[] result = new byte[innerKey.length + 26]; System.arraycopy(DECODER.decode("MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKY="), 0, result, 0, 26); System.arraycopy(BigInteger.valueOf(result.length - 4).toByteArray(), 0, result, 2, 2); System.arraycopy(BigInteger.valueOf(innerKey.length).toByteArray(), 0, result, 24, 2); System.arraycopy(innerKey, 0, result, 26, innerKey.length); return result; } 

एक बार उस विधि के बाद आप इसका उत्पादन PKCS8EncodedKeySpec कन्स्ट्रक्टर को पा सकते हैं: new PKCS8EncodedKeySpec(buildPKCS8Key(privateKey));

सुनिश्चित करें कि आपकी id_rsa फ़ाइल में .txt या .rtf जैसी कोई एक्सटेंशन नहीं है रिच टेक्स्ट फ़ॉर्मेट आपकी फ़ाइल में अतिरिक्त वर्ण जोड़ता है और उनको बाइट सरणी में जोड़ा जाता है। जो अंततः अवैध निजी कुंजी त्रुटि का कारण बनता है लंबी कहानी छोटी, फ़ाइल कॉपी करें, न कि सामग्री।