Jak mogę dokonać transformacji między dwoma stylami formatu klucza publicznego, jeden format to:
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
inny format to:
-----BEGIN RSA PUBLIC KEY-----
...
-----END RSA PUBLIC KEY-----
na przykład wygenerowałem parę id_rsa / id_rsa.pub za pomocą polecenia ssh-keygen, obliczyłem klucz publiczny z id_rsa używając:
openssl rsa -in id_rsa -pubout -out pub2
potem znowu obliczyłem klucz publiczny z id_rsa.pub używając:
ssh-keygen -f id_rsa.pub -e -m pem > pub1
zawartość to pub1 to:
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA61BjmfXGEvWmegnBGSuS+rU9soUg2FnODva32D1AqhwdziwHINFa
D1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBSEVCgJjtHAGZIm5GL/KA86KDp/CwDFMSw
luowcXwDwoyinmeOY9eKyh6aY72xJh7noLBBq1N0bWi1e2i+83txOCg4yV2oVXhB
o8pYEJ8LT3el6Smxol3C1oFMVdwPgc0vTl25XucMcG/ALE/KNY6pqC2AQ6R2ERlV
gPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeulmCpGSynXNcpZ/06+vofGi/2MlpQZNhH
Ao8eayMp6FcvNucIpUndo1X8dKMv3Y26ZQIDAQAB
-----END RSA PUBLIC KEY-----
a zawartość pub2 to:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA61BjmfXGEvWmegnBGSuS
+rU9soUg2FnODva32D1AqhwdziwHINFaD1MVlcrYG6XRKfkcxnaXGfFDWHLEvNBS
EVCgJjtHAGZIm5GL/KA86KDp/CwDFMSwluowcXwDwoyinmeOY9eKyh6aY72xJh7n
oLBBq1N0bWi1e2i+83txOCg4yV2oVXhBo8pYEJ8LT3el6Smxol3C1oFMVdwPgc0v
Tl25XucMcG/ALE/KNY6pqC2AQ6R2ERlVgPiUWOPatVkt7+Bs3h5Ramxh7XjBOXeu
lmCpGSynXNcpZ/06+vofGi/2MlpQZNhHAo8eayMp6FcvNucIpUndo1X8dKMv3Y26
ZQIDAQAB
-----END PUBLIC KEY-----
Zgodnie z moim zrozumieniem pub1 i pub2 zawierają te same informacje o kluczu publicznym, ale są w innym formacie, zastanawiam się, jak mogę zmienić między tymi dwoma formatami? Czy ktoś może mi pokazać zwięzłe wprowadzenie do formatów holowania?
Odpowiedzi:
Korzystanie z phpseclib, czystej implementacji PHP RSA ...
Wydaje się, że elementy zakodowane w base64 pasują do siebie, mimo że w nagłówku jest napisane BEGIN PUBLIC KEY, a nie BEGIN RSA PUBLIC KEY. Więc może po prostu użyj str_replace, aby to naprawić i powinieneś być gotowy!
źródło
Chciałem pomóc wyjaśnić, co się tutaj dzieje.
„Klucz publiczny” RSA składa się z dwóch liczb:
Na przykładzie klucza publicznego RSA te dwie liczby to:
Powstaje zatem pytanie, w jaki sposób chcemy przechowywać te liczby w komputerze. Najpierw konwertujemy oba na szesnastkowe:
RSA wynalazł pierwszy format
RSA jako pierwszy wymyślił format:
Zdecydowali się użyć odmiany DER standardu kodowania binarnego ASN.1 do reprezentowania dwóch liczb [1] :
Ostateczne kodowanie binarne w ASN.1 to:
Jeśli następnie uruchomisz wszystkie te bajty razem i zakodujesz je Base64, otrzymasz:
Następnie laboratoria RSA powiedziały, że dodaj nagłówek i zwiastun:
Pięć łączników i słowa
BEGIN RSA PUBLIC KEY
. To jest Twój klucz publiczny PEM DER ASN.1 PKCS # 1 RSANie tylko RSA
Potem pojawiły się inne formy kryptografii klucza publicznego:
Kiedy nadszedł czas, aby stworzyć standard reprezentacji parametrów tych algorytmów szyfrowania, ludzie przyjęli wiele z tych samych pomysłów, które pierwotnie zdefiniowało RSA:
BEGIN PUBLIC KEY
Ale zamiast używać:
-----BEGIN RSA PUBLIC KEY-----
-----BEGIN DH PUBLIC KEY-----
-----BEGIN EC PUBLIC KEY-----
Postanowili zamiast tego dołączyć identyfikator obiektu (OID) tego, co ma nastąpić. W przypadku klucza publicznego RSA jest to:
1.2.840.113549.1.1.1
Więc dla klucza publicznego RSA był to zasadniczo:
Teraz stworzyli SubjectPublicKeyInfo, który jest w zasadzie:
W rzeczywistości definicja DER ASN.1 to:
To daje ASN.1 z:
Ostateczne kodowanie binarne w ASN.1 to:
I tak jak poprzednio, bierzesz wszystkie te bajty, koduje je Base64, kończysz na drugim przykładzie:
Dodaj nieco inny nagłówek i zwiastun, a otrzymasz:
A to jest Twój klucz publiczny X.509 SubjectPublicKeyInfo / OpenSSL PEM [2] .
Zrób to dobrze lub zhakuj
Teraz, gdy wiesz, że kodowanie nie jest magiczne, możesz napisać wszystkie elementy potrzebne do przeanalizowania modułu i wykładnika RSA. Lub możesz rozpoznać, że pierwsze 24 bajty to po prostu dodane nowe rzeczy w stosunku do oryginalnego standardu PKCS # 1
Te pierwsze 24 bajty to „nowe” dodane rzeczy:
A dzięki niezwykłemu zbiegowi okoliczności i powodzenia:
Ponieważ w Base64: 3 bajty to cztery znaki:
Oznacza to, że jeśli weźmiesz drugi klucz publiczny X.509, pierwsze 32 znaki odpowiadają tylko nowo dodanym elementom:
Jeśli usuniesz pierwsze 32 znaki i zmienisz je na BEGIN RSA PUBLIC KEY :
Masz dokładnie to, czego chciałeś - starszy
RSA PUBLIC KEY
format.źródło
Uważam, że ta strona internetowa jest dobrym technicznym wyjaśnieniem różnych formatów: https://polarssl.org/kb/cryptography/asn1-key-structures-in-der-and-pem
„BEGIN RSA PUBLIC KEY” to PKCS # 1, który może zawierać tylko klucze RSA.
„BEGIN PUBLIC KEY” to PKCS # 8, który może zawierać różne formaty.
Jeśli chcesz je po prostu przekonwertować za pomocą wiersza poleceń, "openssl rsa" jest do tego dobra.
Aby przekonwertować z PKCS # 8 na PKCS # 1:
Aby przekonwertować z PKCS # 1 na PKCS # 8:
źródło
unknown option -RSAPublicKey_in
Chociaż powyższe komentarze dotyczące 32-bajtowych nagłówków, formatów OID i tym podobnych są interesujące, osobiście nie widzę tego samego zachowania, zakładając, że rozumiem. Pomyślałem, że pomocne może być dalsze zbadanie tego, co większość może uważać za nadmierne szczegóły. Nie ma nic lepszego niż nadmiar.
Na początek utworzyłem klucz prywatny RSA i sprawdziłem go:
(Och, okropności! Ujawniłem klucz prywatny. Meh ...)
Wyodrębniam i wyświetlam jego klucz publiczny:
Tak się składa, że istnieje inny parametr wyjściowy klucza publicznego (jak wspomniano we wcześniejszym komentarzu). Wyodrębniam i wyświetlam klucz publiczny za pomocą tego słowa kluczowego:
Dobrze, dobrze. Te dwie wartości klucza publicznego nie są takie same, chociaż pochodzą z tego samego klucza prywatnego. A może są takie same? Wycinam i wklejam dwa ciągi kluczy publicznych do ich własnych plików, a następnie sprawdzam każdy z nich:
The „pubin” mówi RSA, że to naprawdę jest ma być klucz publiczny i nie skarżą się, że nie jest to klucz prywatny.
Teraz bierzemy publiczny klucz RSA, wyświetlamy moduł i przekształcamy go w zwykły stary „klucz publiczny” (znowu musimy powiedzieć, że dane wejściowe są kluczem publicznym):
Ten sam moduł i ta sama wartość „klucza publicznego”. Aby uczynić rzeczy bardziej interesującymi (w każdym razie dla mnie), kiedy dodamy słowo kluczowe RSAPublicKey_out , otrzymujemy:
... i kiedy transmogryfikujemy zwykły stary „klucz publiczny” w klucz publiczny RSA:
... maszerujesz nieubłaganie i chociaż zrobiliśmy to kilka poleceń temu, aby podkreślić, że odwrócimy rzeczy, aby transmogryfikacja przebiegała z RSA do zwykłego starego „klucza publicznego”:
... co prowadzi nas z powrotem do miejsca, w którym zaczęliśmy. Czego się nauczyliśmy?
Podsumowanie: klucze wewnętrznie są takie same, po prostu wyglądają inaczej. Wcześniejszy komentarz wskazywał, że format klucza RSA został zdefiniowany w PKCS # 1, a zwykły stary format „klucza publicznego” został zdefiniowany w PKCS # 8. Jednak edycja jednego formularza nie zmienia go w drugi. Mam nadzieję, że pokonałem to wyróżnienie na śmierć.
Jednak na wypadek, gdyby pozostała jeszcze iskierka życia, zacznijmy trochę więcej i odwołajmy się do certyfikatu, który został pierwotnie wygenerowany z kluczem prywatnym RSA tak dawno temu, badając jego klucz publiczny i moduł:
... i wszyscy żyli długo i szczęśliwie: certyfikat ma taką samą wartość modułu, jak klucz publiczny RSA, klucz prywatny RSA i zwykły stary „klucz publiczny”. Certyfikat zawiera tę samą zwykłą wartość „klucza publicznego”, którą widzieliśmy wcześniej, chociaż został podpisany plikiem oznaczonym jako klucz prywatny RSA. Można śmiało powiedzieć, że istnieje konsensus.
W kwadrancie X509 galaktyki OpenSSL nie ma odpowiednika słowa kluczowego „RSAPublicKey_out”, więc nie możemy tego wypróbować, chociaż wartość modułu jest opisana jako „kluczowy moduł RSA”, który, jak przypuszczam, jest tak blisko, jak to tylko możliwe.
Jak to wszystko wyglądałoby z certyfikatem podpisanym przez DSA, nie wiem.
Zdaję sobie sprawę, że to nie odpowiada na pierwotne pytanie, ale być może dostarcza przydatnych informacji. Jeśli nie, przepraszam. Przynajmniej rzeczy, których nie należy robić i założenia, których nie należy robić.
Bez wątpienia można zauważyć nieco irytujące powtarzanie się „pisania klucza RSA”, kiedy nie robi się czegoś takiego. Zakładam, że chodziło o to, że moduł rsa rozpoznaje zwykły stary klucz publiczny jako prawdziwy klucz RSA, i dlatego ciągle używa „klucza RSA” (a ponadto jest to w końcu moduł rsa). Jeśli dobrze pamiętam, ogólna struktura EVP_PKEY ma unię dla wszystkich typów kluczy, przy czym każdy typ klucza ma swój własny specjalny zestaw wartości (pomocna nazwa g, w, q i inne spółgłoski).
Podsumowując, zauważam, że była skarga dotycząca programowania i rozwoju; teraz każde polecenie OpenSSL ma oczywiście odpowiadający mu kod, a jeśli ktoś chciałby zbadać wszystkie cuda, którymi jest dziś programowanie OpenSSL, wiersz poleceń wydaje się rozsądnym miejscem do rozpoczęcia. W tym konkretnym przypadku (ponieważ w tej chwili używam najnowszego cygwina) można zacząć od przejrzenia \ openssl-1.0.2f \ apps \ rsa.c i (biorąc pod uwagę, że ma on dużą tolerancję na makra) \ openssl-1.0. 2f \ crypto \ pem \ pem_all.c
źródło
Różnica tylko między pub1 i pub2 oprócz nagłówka / stopki, jest to dodatkowy ciąg w pub2:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
. Jeśli to usuniesz, Base 64 będzie identyczny z tym w pub1.Dodatkowy ciąg odpowiada identyfikatorowi algorytmu zgodnie z tą odpowiedzią .
źródło