Ako čítať súbory PEM a získať verejné a súkromné ​​kľúče

Java Top

Práve som oznámil nové Naučte sa jar kurz zameraný na základy jari 5 a Spring Boot 2:

>> SKONTROLUJTE KURZ

1. Prehľad

V kryptografii s verejným kľúčom (tiež známa ako asymetrická kryptografia) sa šifrovací mechanizmus spolieha na dva súvisiace kľúče, verejný kľúč a súkromný kľúč. Verejný kľúč sa používa na šifrovanie správy, zatiaľ čo správu môže dešifrovať iba vlastník súkromného kľúča.

V tejto príručke sa dozvieme, ako čítať verejné a súkromné ​​kľúče zo súboru PEM.

Najskôr si preštudujeme niekoľko dôležitých konceptov kryptografie s verejným kľúčom. Potom sa naučíme čítať súbory PEM pomocou čistej Javy.

Na záver preskúmame knižnicu BouncyCastle ako alternatívny prístup.

2. Koncepty

Skôr ako začneme, pochopme niektoré kľúčové pojmy.

X.509 je štandard definujúci formát certifikátov verejného kľúča. Tento formát teda okrem iných informácií popisuje verejný kľúč.

DER je najpopulárnejší formát kódovania na ukladanie údajov, ako sú certifikáty X.509, súkromné ​​kľúče PKCS8, do súborov. Je to binárne kódovanie a výsledný obsah nie je možné zobraziť v textovom editore.

PKCS8 je štandardná syntax na ukladanie informácií o súkromnom kľúči. Súkromný kľúč je možné voliteľne zašifrovať pomocou symetrického algoritmu.

Týmto štandardom možno manipulovať nielen so súkromnými kľúčmi RSA, ale aj s inými algoritmami. Súkromné ​​kľúče PKCS8 sa zvyčajne vymieňajú prostredníctvom formátu kódovania PEM.

PEM je kódovací mechanizmus base-64 certifikátu DER. PEM môže tiež kódovať ďalšie druhy údajov, ako sú verejné / súkromné ​​kľúče a žiadosti o certifikáty.

Súbor PEM obsahuje aj hlavičku a pätu popisujúcu typ kódovaných údajov:

----- ZAČÍNAME VEREJNÝ KĽÚČ ----- ... Base64 kódovanie certifikátu kódovaného DER ... ----- KONIEC VEREJNÝ KĽÚČ -----

3. Používanie čistej Javy

3.1. Čítanie údajov PEM zo súboru

Začnime tým, že si prečítame súbor PEM a uložíme jeho obsah do reťazca:

Kľúč reťazca = nový reťazec (Files.readAllBytes (file.toPath ()), Charset.defaultCharset ());

3.2. Získajte verejný kľúč z reťazca PEM

Chystáme sa vytvoriť metódu nástroja, ktorá získa verejný kľúč z reťazca kódovaného PEM:

----- BEGIN PUBLIC KEY ----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsjtGIk8SxD + OEiBpP2 / T JUAF0upwuKGMk6wH8Rwov88VvzJrVm2NCticTk5FUg + UG5r8JArrV4tJPRHQyvqK wF4NiksuvOjv3HyIf4oaOhZjT8hDne1Bfv + cFqZJ61Gk0MjANh / T5q9vxER / 7TdU NHKpoRV + NVlKN5bEU / NQ5FQjVXicfswxh6Y6fl2PIFqT2CfjD + FkBPU1iT9qyJYH A38IRvwNtcitFgCeZwdGPoxiPPh1WHY8VxpUVBv / 2JsUtrB / rAIbGqZoxAIWvijJ Pe9o1TY3VlOzk9ASZ1AeatvOir + iDVJ5OpKmLnzc46QgGPUsjIyo6Sje9dxpGtoG QQIDAQAB ----- END VEREJNÝ KLÍČ -----

Predpokladajme, že dostaneme Súbor ako parameter:

public static RSAPublicKey readPublicKey (File file) throws Exception {String key = new String (Files.readAllBytes (file.toPath ()), Charset.defaultCharset ()); Reťazec publicKeyPEM = kľúč .replace ("----- ZAČÍNAME VEREJNÝ KĽÚČ -----", "") .replaceAll (System.lineSeparator (), "") .replace ("----- UKONČIŤ VEREJNÝ KĽÚČ ----- "," "); byte [] zakódovaný = Base64.decodeBase64 (publicKeyPEM); KeyFactory keyFactory = KeyFactory.getInstance ("RSA"); X509EncodedKeySpec keySpec = nový X509EncodedKeySpec (kódovaný); návrat (RSAPublicKey) keyFactory.generatePublic (keySpec); }

Ako vidíme, najskôr musíme odstrániť hlavičku, pätu a tiež nové riadky. Potom musíme dekódovať reťazec kódovaný pomocou Base64 do zodpovedajúceho binárneho formátu.

Ďalej musíme výsledok načítať do triedy špecifikácie kľúča, ktorá je schopná spracovať materiál verejného kľúča. V našom prípade použijeme X509EncodedKeySpec trieda.

Nakoniec môžeme zo špecifikácie vygenerovať objekt verejného kľúča pomocou KeyFactory trieda.

3.3. Získajte súkromný kľúč z reťazca PEM

Teraz, keď vieme, ako čítať verejný kľúč, je algoritmus čítania súkromného kľúča veľmi podobný.

Použijeme súkromný kľúč kódovaný PEM vo formáte PKCS8. Pozrime sa, ako vyzerá hlavička a päta:

----- ZAČÍNAME SÚKROMNÝ KLÍČ ----- ... Kľúč kódovaný v Base64 ... ----- UKONČIŤ SÚKROMNÝ KĽÚČ -----

Ako sme sa už predtým dozvedeli, potrebujeme triedu, ktorá dokáže spracovať kľúčový materiál PKCS8. The PKCS8EncodedKeySpec triedy plní túto úlohu.

Pozrime sa teda na algoritmus:

public RSAPrivateKey readPrivateKey (File file) throws Exception {String key = new String (Files.readAllBytes (file.toPath ()), Charset.defaultCharset ()); Reťazec privateKeyPEM = kľúč .replace ("----- ZAČÍNAME PRIVÁTNY KLÍČ -----", "") .replaceAll (System.lineSeparator (), "") .replace ("----- UKONČIŤ PRIVÁTNY KĽÚČ ----- "," "); byte [] kódované = Base64.decodeBase64 (privateKeyPEM); KeyFactory keyFactory = KeyFactory.getInstance ("RSA"); PKCS8EncodedKeySpec keySpec = nový PKCS8EncodedKeySpec (kódovaný); návrat (RSAPrivateKey) keyFactory.generatePrivate (keySpec); }

4. Používanie knižnice BouncyCastle

4.1. Prečítajte si verejný kľúč

Ideme preskúmať knižnicu BouncyCastle a uvidíme, ako ju možno použiť ako alternatívu k čistej implementácii Java.

Poďme získať verejný kľúč:

public RSAPublicKey readPublicKey (súborový súbor) vyvolá výnimku {KeyFactory factory = KeyFactory.getInstance ("RSA"); try (FileReader keyReader = nový FileReader (súbor); PemReader pemReader = nový PemReader (keyReader)) {PemObject pemObject = pemReader.readPemObject (); byte [] obsah = pemObject.getContent (); X509EncodedKeySpec pubKeySpec = nový X509EncodedKeySpec (obsah); návrat (RSAPublicKey) factory.generatePublic (pubKeySpec); }}

Pri používaní BouncyCastle si musíme uvedomiť niekoľko dôležitých tried:

  • PemReader - vezme a Čitateľ ako parameter a analyzuje jeho obsah. Odstráni zbytočné hlavičky a dekóduje podkladové dáta Base64 PEM do binárneho formátu.
  • PemObject uloží výsledok vygenerovaný PemReader.

Okrem toho sa pozrime na ďalší prístup, ktorý obaľuje triedy Java (X509EncodedKeySpec, KeyFactory) do vlastnej triedy BouncyCastle (JcaPEMKeyConverter):

public RSAPublicKey readPublicKeySecondApproach (File file) throws IOException {try (FileReader keyReader = new FileReader (file)) {PEMParser pemParser = new PEMParser (keyReader); Prevodník JcaPEMKeyConverter = nový JcaPEMKeyConverter (); SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfo.getInstance (pemParser.readObject ()); return (RSAPublicKey) converter.getPublicKey (publicKeyInfo); }}

4.2. Prečítajte si súkromný kľúč

Uvidíme dva príklady, ktoré sú veľmi podobné tým, ktoré sú uvedené vyššie.

V prvom príklade stačí nahradiť X509EncodedKeySpec trieda s PKCS8EncodedKeySpec triedy a vrátiť RSAPrivateKey objekt namiesto RSAPublicKey:

public RSAPrivateKey readPrivateKey (File file) throws Exception {KeyFactory factory = KeyFactory.getInstance ("RSA"); try (FileReader keyReader = nový FileReader (súbor); PemReader pemReader = nový PemReader (keyReader)) {PemObject pemObject = pemReader.readPemObject (); byte [] obsah = pemObject.getContent (); PKCS8EncodedKeySpec privKeySpec = nový PKCS8EncodedKeySpec (obsah); návrat (RSAPrivateKey) factory.generatePrivate (privKeySpec); }}

Poďme teraz trochu prepracovať druhý prístup z predchádzajúcej časti, aby sme si mohli prečítať súkromný kľúč:

public RSAPrivateKey readPrivateKeySecondApproach (File file) throws IOException {try (FileReader keyReader = new FileReader (file)) {PEMParser pemParser = new PEMParser (keyReader); Prevodník JcaPEMKeyConverter = nový JcaPEMKeyConverter (); PrivateKeyInfo privateKeyInfo = PrivateKeyInfo.getInstance (pemParser.readObject ()); return (RSAPrivateKey) converter.getPrivateKey (privateKeyInfo); }}

Ako vidíme, práve sme nahradili SubjectPublicKeyInfo s PrivateKeyInfo a RSAPublicKey s RSAPrivateKey.

4.3. Výhody

Knižnica BouncyCastle poskytuje niekoľko výhod.

Jednou výhodou je, že nemusíme manuálne preskakovať alebo odstraňovať hlavičku a pätu. Ďalším je to nie sme zodpovední za dekódovanie Base64 buď. Preto môžeme pomocou programu BouncyCastle písať menej náchylný kód.

Okrem toho Knižnica BouncyCastle podporuje formát PKCS1 tiež. Napriek skutočnosti, že PKCS1 je tiež populárny formát používaný na ukladanie kryptografických kľúčov (iba kľúče RSA), Java ho sama o sebe nepodporuje.

5. Záver

V tomto článku sme sa naučili, ako čítať verejné a súkromné ​​kľúče zo súborov PEM.

Najprv sme študovali niekoľko kľúčových konceptov kryptografie verejných kľúčov. Potom sme videli, ako čítať verejné a súkromné ​​kľúče pomocou čistej Javy.

Na záver sme preskúmali knižnicu BouncyCastle a zistili sme, že je to dobrá alternatíva, pretože poskytuje niekoľko výhod v porovnaní s čistou implementáciou Java.

Celý zdrojový kód pre prístupy Java a BouncyCastle je k dispozícii na GitHub.

Java dole

Práve som oznámil nové Naučte sa jar kurz zameraný na základy jari 5 a Spring Boot 2:

>> SKONTROLUJTE KURZ