Can some one help me understand how an RSA key literally is stored in these formats? I would like to know the difference between the PKCS formats vs Encodings(DER, PEM). From what I understand PEM is more human readable. Is PEM/DER for keys/certs similar to UTF-8/16 for characters? What is the significance of DER/PEM? Sorry too many questions but fed up googling and getting vague answers. Thanks.
PKCS#1 and PKCS#8 (Public-Key Cryptography Standard) are standards that govern the use of particular cryptographic primitives, padding, etc. Both define file formats that are used to store keys, certificates, and other relevant information.
PEM and DER are a little bit more interesting. DER is the ASN.1 encoding for keys and certificates etc., which you'll be able to Google plenty about. Private keys and certificates are encoded using DER and can be saved directly like this. However, these files are binary and can't be copied and pasted easily, so many (if not most?) implementations accept PEM encoded files also. PEM is basically base64 encoded DER: we add a header, optional meta-data, and the base64 encoded DER data and we have a PEM file.
(Expanding more than I feel is appropriate for an edit.)
PKCS1, available in several versions as rfcs 2313 2437 3447 and 8017, is primarily about using the RSA algorithm for cryptography including encrypting decrypting signing and verifying. But since crypto is often used between systems or at least programs it is convenient to have a defined, interoperable format for keys, and PKCS1 defines fairly minimal formats for RSA public and private keys in appendix A.1. As Luke implied this uses ASN.1 conventionally encoded as DER, which is a standard for interoperably encoding data of almost any kind.
PKCS8 available as rfc5208 on the other hand is a standard for handling private keys for all algorithms, not just RSA. It also uses ASN.1 DER, and starts by simply combining an AlgorithmIdentifier
, an ASN.1 structure (first) defined by X.509 which not very surprisingly identifies an algorithm, with an OCTET STRING
which contains a representation of the key in a fashion depending on the algorithm. For algorithm RSA, identified by an AlgorithmIdentifier containing an OID which means rsaEncryption, the OCTET STRING contains the PKCS1 private key encoding.
PKCS8 also allows arbitrary 'attributes' to be added, but this is rarely used.
(E.g. Unable to convert .jks to .pkcs12: excess private key)
PKCS8 also provides an option to encrypt the private key, using password-based encryption (in practice though not explicitly required). This is common, especially when PKCS8 is used as the privatekey portion of PKCS12/PFX, though not universal.
Since most systems today need to support multiple algorithms, and wish to be able to adapt to new algorithms as they are developed, PKCS8 is preferred for privatekeys, and a similar any-algorithm scheme defined by X.509 for publickeys. Although PKCS12/PFX is often preferred to both.
Neither of these has anything to do with certificates or other PKI objects like CSRs, CRLs, OCSP, SCTs, etc. Those are defined by other standards, including some other members of the PKCS series -- although they may use the keys defined by these standards.
PEM format as Luke said is a way of formatting, or (super)encoding, (almost any) binary/DER data in a way that is more convenient. It derives from a 1990s attempt at secure email named Privacy-Enhanced Mail hence PEM. In those days email systems often could transmit, or at least reliably transmit, only printable text with a limited character set, and often only limited line length, so PEM encoded binary data as base64 with line length 64. The PEM scheme itself was not very successful and has been superseded by others like PGP and S/MIME, but the format it defined is still used. Nowadays email systems often can transmit binary data, but as Luke said copy-and-paste often can only handle displayed characters so PEM is still useful, and in addition easier for humans to recognize.
To be more exact, PEM encodes some data, such as but not limited to a PKCS1 or PKCS8 key or a certificate, CSR, etc, as:
a line consisting of 5 hyphens, the word BEGIN, one or a few (space-separated) words defining the type of data, and 5 hyphens
an optional (and rare) rfc822-style header, terminated by an empty line
base64 of the data, broken into lines of 64 characters (except the last); some programs instead use the (slightly newer) MIME limit of 76 characters
a line like the BEGIN line but with END instead
Some readers check/enforce the line length and END line and some don't, so if you get those wrong you may create files that sometimes work and sometimes don't, which is annoying to debug.
Thus for example a PKCS1 private key (unencrypted) in PEM looks like:
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCjcGqTkOq0CR3rTx0ZSQSIdTrDrFAYl29611xN8aVgMQIWtDB/
lD0W5TpKPuU9iaiG/sSn/VYt6EzN7Sr332jj7cyl2WrrHI6ujRswNy4HojMuqtfa
b5FFDpRmCuvl35fge18OvoQTJELhhJ1EvJ5KUeZiuJ3u3YyMnxxXzLuKbQIDAQAB
AoGAPrNDz7TKtaLBvaIuMaMXgBopHyQd3jFKbT/tg2Fu5kYm3PrnmCoQfZYXFKCo
ZUFIS/G1FBVWWGpD/MQ9tbYZkKpwuH+t2rGndMnLXiTC296/s9uix7gsjnT4Naci
5N6EN9pVUBwQmGrYUTHFc58ThtelSiPARX7LSU2ibtJSv8ECQQDWBRrrAYmbCUN7
ra0DFT6SppaDtvvuKtb+mUeKbg0B8U4y4wCIK5GH8EyQSwUWcXnNBO05rlUPbifs
DLv/u82lAkEAw39sTJ0KmJJyaChqvqAJ8guulKlgucQJ0Et9ppZyet9iVwNKX/aW
9UlwGBMQdafQ36nd1QMEA8AbAw4D+hw/KQJBANJbHDUGQtk2hrSmZNoV5HXB9Uiq
7v4N71k5ER8XwgM5yVGs2tX8dMM3RhnBEtQXXs9LW1uJZSOQcv7JGXNnhN0CQBZe
nzrJAWxh3XtznHtBfsHWelyCYRIAj4rpCHCmaGUM6IjCVKFUawOYKp5mmAyObkUZ
f8ue87emJLEdynC1CLkCQHduNjP1hemAGWrd6v8BHhE3kKtcK6KHsPvJR5dOfzbd
HAqVePERhISfN6cwZt5p8B3/JUwSR8el66DF7Jm57BM=
-----END RSA PRIVATE KEY-----
The same key in PKCS8 unencrypted:
-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKNwapOQ6rQJHetP
HRlJBIh1OsOsUBiXb3rXXE3xpWAxAha0MH+UPRblOko+5T2JqIb+xKf9Vi3oTM3t
KvffaOPtzKXZauscjq6NGzA3LgeiMy6q19pvkUUOlGYK6+Xfl+B7Xw6+hBMkQuGE
nUS8nkpR5mK4ne7djIyfHFfMu4ptAgMBAAECgYA+s0PPtMq1osG9oi4xoxeAGikf
JB3eMUptP+2DYW7mRibc+ueYKhB9lhcUoKhlQUhL8bUUFVZYakP8xD21thmQqnC4
f63asad0ycteJMLb3r+z26LHuCyOdPg1pyLk3oQ32lVQHBCYathRMcVznxOG16VK
I8BFfstJTaJu0lK/wQJBANYFGusBiZsJQ3utrQMVPpKmloO2++4q1v6ZR4puDQHx
TjLjAIgrkYfwTJBLBRZxec0E7TmuVQ9uJ+wMu/+7zaUCQQDDf2xMnQqYknJoKGq+
oAnyC66UqWC5xAnQS32mlnJ632JXA0pf9pb1SXAYExB1p9Dfqd3VAwQDwBsDDgP6
HD8pAkEA0lscNQZC2TaGtKZk2hXkdcH1SKru/g3vWTkRHxfCAznJUaza1fx0wzdG
GcES1Bdez0tbW4llI5By/skZc2eE3QJAFl6fOskBbGHde3Oce0F+wdZ6XIJhEgCP
iukIcKZoZQzoiMJUoVRrA5gqnmaYDI5uRRl/y57zt6YksR3KcLUIuQJAd242M/WF
6YAZat3q/wEeETeQq1wrooew+8lHl05/Nt0cCpV48RGEhJ83pzBm3mnwHf8lTBJH
x6XroMXsmbnsEw==
-----END PRIVATE KEY-----
and PKCS8 encrypted:
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIC3TBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIkErtXjGCalMCAggA
MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBApOUG3MKrBC/5bDBH/s5VfBIIC
gN5o1aJxvJYbp2oA/quz+BnCFn8ts3wPPOcqarHddy0L/VH3BdqFNbnPZEaDnvDl
kqChRsti4AAeX18ItMeAyNLNFv0J4mfI8Q5E7iEnPp+dTsZqNfVIJe2NGxOS7zp2
oQQIZVgjW0akDehv6ZDN796qDBlMY2g80wbBrzVgMJu/byG9IQQjngUE9QNGwrsj
7lYSprxjfTZOk1aGBD0d/HsmetIJvCeJ2i/5xAiGgZRrSWMC6aN7Zlra3eIvHQTB
aKZ8/0IT3iKSr6FpkEopOQae8biiTEVGw9D339P3qOSs2ChWWF+OV2sEA67w6q5j
pz6Poc5jgq4FOcf06GdcVa4tst2uykNJCW0wHpcUR1Tr9ILLhrZPYBYVQWW53Eee
o4+mqW2YORdG3a/jLHpEjL0Vdg95QNpdZoMv8plotN1MUBLebd05aCe5hJUb/x74
3GTwmRGmKoHOhOO3hhUaMCmZIg1xPlNT3jqxrZDoATBeONbaFP8OOkeucVYHbdUO
Ad7z6J8XuZDoxM0BVrGykEiQL2nAOccdsGoC33C9hjkqgU8G9jWElbynJlVqv+1a
lFHWjX5lB6ueiY/rClpVlLmXGB83OVPlo70FV0B9rhRChyB1IJJRYPFDJHSHJNu+
Pqay8zw82Gh/G+TWH/JCLm5YjX55ZSFMUmvwOLaxyQpmAGNH6dIBTAaSctVA7UrV
jm7m+5T7seiNYNEi19vDJipgr0GbX8+np47VrsJDxsS20wTeA/9ltD0xXwNrEKHd
2Nv/1OaCgnBQHIGULgEn9pT3/vU87bBHYjVdrWoUmqd9zFYtdImQE9u8IKTxTe4R
UPRGHqltz4uOjbD1epkSGe0=
-----END ENCRYPTED PRIVATE KEY-----
Observe the type of data in each file (or other data unit) is easily recognized from the BEGIN/END lines. The actual key values in the data are not easily read without tools, although only the third actually needs secret information (the password used to encrypt).
来源:https://stackoverflow.com/questions/48958304/pkcs1-and-pkcs8-format-for-rsa-private-key