jeroen / openssl

OpenSSL bindings for R
Other
64 stars 22 forks source link

HOWTO write unencrypted private key #43

Closed jgbradley1 closed 7 years ago

jgbradley1 commented 7 years ago

Is it possible to write an unencrypted private key to file if it was encrypted when read in? Right now I have to rely on the PKI package to do this, like so:

# using a test p12 cert with password "fred"
p12.encrypted.file <- "fred.p12"

# extract private key
p12 <- openssl::read_p12(file=p12.encrypted.file, password = "fred")
cert_key <- openssl::write_pem(p12$key)

# write encrypted key
ekey.file = tempfile()
write(cert_key, file=ekey.file)

# write decrypted key
key <- PKI::PKI.load.key(file=ekey.file, password="fred")
decrypted_key <- PKI::PKI.save.key(key, format="PEM", private=TRUE)
decrypt.key.file <- tempfile()
write(decrypted_key, file=decrypt.key.file)
jeroen commented 7 years ago

I think your line openssl::write_pem(p12$key) already does this? The write_pem function will only add a password if you specify one.

jgbradley1 commented 7 years ago

Here's what I've been seeing. Not sure if it's a bug or not. I created a fake p12 file to test on. I used commandline openssl to extract and decrypt the private key for comparison. I also extracted and encrypted the private key for comparison. The signature for ekey.file does not match the encrypted private key that commandline openssl creates. However using the code above with the PKI package, I can confirm the signature for decrypt.key.file does match the decrypted private key generated by commandline openssl.

If you want to test out what I'm seeing, check out the attached file for the fake p12 cert. It was created purely for testing, as was the CA authority cert used to sign it so no security risk. The password on it is fred

test_pki_cert.zip

jeroen commented 7 years ago

I just get:

> p12 <- openssl::read_p12("fred.p12", password = "password")
Error: PKCS12 read failure: invalid password
jgbradley1 commented 7 years ago

Sorry if I wasn't clear. I left out the default password in the code above in case you tested it on a different p12. I've updated the original comment to correspond to the test p12 cert now. It should be read in like

p12 <- openssl::read_p12("fred.p12", password = "fred")

jeroen commented 7 years ago

I don't understand why you think there is a password on the pem:

p12 <- openssl::read_p12("fred.p12", password = "fred")
write_pem(p12$key, "mykey.rsa")

You can read the pem file without entering a password:

key <- read_key("mykey.rsa")
identical(key, p12$key) 
#TRUE

You can recognize a password protected key by its ENCRYPTED header:

pem_text <- write_pem(p12$key, password = "fred")
cat(pem_text)
read_key(pem_text) # wil prompt for password
jgbradley1 commented 7 years ago

You are correct. I don't think I am asking the right question. I am trying to replicate the same output as if I were running the following openssl command from the command line:

> openssl pkcs12 -nomacver -nocerts -nodes -in fred.p12 -out commandline_fred.key
> cat commandline_fred.key
Bag Attributes
    localKeyID: 7A 89 46 B9 DB 50 8C 69 22 28 6D 1F B0 58 05 41 79 A8 42 21
    friendlyName: Fred Flintstone
Key Attributes: <No Attributes>
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAuYGsBQTkzg/xiuMS2088wq8yWkNj1pP/8VNMeLnq4abwQZEE
MKz+jrN+5oRDFPLbMz0tPynOy+XN6rWcNQ/OJhoBmVBHbL4c6RDJMpuObO5byAnn
lctQZgjYf5MIhqnwS75sFUYY9qZF6E2JvesHagPaNYHWsNME2wi52DNXOQ/rI53d
9dXeDIMacdiShPFDt0FNEArdstuy4+8TmDQeqjF5bzlQSOCFAcSwbjIfhDpbilID
1PElD/E01J/OceDBTYLaZTctl9iY1mzHRl9Stf/15TM++BvDpSglyVqQl24jrjgr
acjernu8nkUQ4LfjIPX65xi+3BtdPrYrPoXCmQIDAQABAoIBAQCN0GDmEWCtWyjn
aUKAH+ouVuricERBxTDTlz+Nx2uViB6BsVAHuih8hSINLa1utV33pNwTPm3WGF88
AAxj0CpjnFv+jY2cxxWo4uk85AiUo//MRC4jqKNU7Yw8svXApOeLsA5GkSkCXghx
V91mL+eiF0HYx+KNmTRMEjao3k7e0kxCdKaIW8E2UoMdUFcmsllKHkNoRK2T/uwU
Q/naIxJ4vPmIXwelDLB/gByAS1ZHrzMHpchHM4cYjotyp3eddTDLb/ZOiYS9yIBh
bzNkwX2SEplJhMdygQuGDnzZOl+jEycIAuxJ1R/uyuH8Sp3OG8esF+WGk65rm7U6
eR5rOGcRAoGBAN8P0etgQamO1ql23b0AhT8v2pHnCoheMzcU7WvEojBHzvs4QYDs
1OZvWdM3NS9trj8ydEwyplgt8Fk5/Fx99IvIaDYiuPwc1Vmwo1WdwUILS65WAJgE
unKuEeukwPrdEL8ssT+tXL5yXboqwcgr0M3Jf1j/HBAyFyqwOFjsS2S9AoGBANTm
MCntW0uu7/qUbm2M6rJorIluGAxR9njmdvfT/pnIymbtmwC5R60ALjEZKzVJ0Lwz
RtGUu2qGtJiJ29Q85R7izn0BL+GEgqU79G69wwrMS1xUYUiDHjSi+KMwbs1evobs
hiCXf2qI+6nX6Oo+1JEnqNJX8bOb21iwcDxIswkNAoGAMXDSOHeHVkvArKMaFtBM
uGqk6X3qSbuHYogS77YPtN/Vsr0PV8ImlkTMBhLQiQiofH10ZYc8c4MLKNu/YcjR
MUJkRst/cPH7H/wU1981fKwARE3vp8I0iUKn2jEUTQY+tgDz8Ic+bT/wIlljxjhf
+ZzVyyYQVE6l7+JLOvp044kCgYEAqP3y20UKQ+Afo0LxCMpjfaxy0D/wnM7umvct
FflTzlRAvUT71a48g8lx4Q0+a/Uk2E7HdxLdVWiJr882DJktsb+M8lLf493gKjKW
CtVcHZUeeLKN6hYSAuwd+sM2IJSFHepfaT14KWOEiEPXISEwb+wQKK8gL1aW3SZo
YKHAY30CgYB2gOcdWWKPsswphXeUbA9rVM8nccHuY5rj6AUZtHVH3j8Nwt+wIzcF
N+APQWvRB2DjMO5XpFiM4vCgUTiHojNXdS36ChMhdgqCxmjpq2wJHy6H20S61V2N
CffigeEPO3GlRnHFKtwUPWPRj4jy1IiSwlI6qKcRKjLfmeBiQzc7BQ==
-----END RSA PRIVATE KEY-----

Now when I use the R openssl package

p12 <- read_p12(file="fred.p12", password="fred")
write_pem(p12$key, path="Ropenssl_fred.key")

The file _Ropensslfred.key looks like:

> cat Ropenssl_fred.key
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC5gawFBOTOD/GK
4xLbTzzCrzJaQ2PWk//xU0x4uerhpvBBkQQwrP6Os37mhEMU8tszPS0/Kc7L5c3q
tZw1D84mGgGZUEdsvhzpEMkym45s7lvICeeVy1BmCNh/kwiGqfBLvmwVRhj2pkXo
TYm96wdqA9o1gdaw0wTbCLnYM1c5D+sjnd311d4Mgxpx2JKE8UO3QU0QCt2y27Lj
7xOYNB6qMXlvOVBI4IUBxLBuMh+EOluKUgPU8SUP8TTUn85x4MFNgtplNy2X2JjW
bMdGX1K1//XlMz74G8OlKCXJWpCXbiOuOCtpyN6ue7yeRRDgt+Mg9frnGL7cG10+
tis+hcKZAgMBAAECggEBAI3QYOYRYK1bKOdpQoAf6i5W6uJwREHFMNOXP43Ha5WI
HoGxUAe6KHyFIg0trW61Xfek3BM+bdYYXzwADGPQKmOcW/6NjZzHFaji6TzkCJSj
/8xELiOoo1TtjDyy9cCk54uwDkaRKQJeCHFX3WYv56IXQdjH4o2ZNEwSNqjeTt7S
TEJ0pohbwTZSgx1QVyayWUoeQ2hErZP+7BRD+dojEni8+YhfB6UMsH+AHIBLVkev
MwelyEczhxiOi3Knd511MMtv9k6JhL3IgGFvM2TBfZISmUmEx3KBC4YOfNk6X6MT
JwgC7EnVH+7K4fxKnc4bx6wX5YaTrmubtTp5Hms4ZxECgYEA3w/R62BBqY7WqXbd
vQCFPy/akecKiF4zNxTta8SiMEfO+zhBgOzU5m9Z0zc1L22uPzJ0TDKmWC3wWTn8
XH30i8hoNiK4/BzVWbCjVZ3BQgtLrlYAmAS6cq4R66TA+t0QvyyxP61cvnJduirB
yCvQzcl/WP8cEDIXKrA4WOxLZL0CgYEA1OYwKe1bS67v+pRubYzqsmisiW4YDFH2
eOZ299P+mcjKZu2bALlHrQAuMRkrNUnQvDNG0ZS7aoa0mInb1DzlHuLOfQEv4YSC
pTv0br3DCsxLXFRhSIMeNKL4ozBuzV6+huyGIJd/aoj7qdfo6j7UkSeo0lfxs5vb
WLBwPEizCQ0CgYAxcNI4d4dWS8CsoxoW0Ey4aqTpfepJu4diiBLvtg+039WyvQ9X
wiaWRMwGEtCJCKh8fXRlhzxzgwso279hyNExQmRGy39w8fsf/BTX3zV8rABETe+n
wjSJQqfaMRRNBj62APPwhz5tP/AiWWPGOF/5nNXLJhBUTqXv4ks6+nTjiQKBgQCo
/fLbRQpD4B+jQvEIymN9rHLQP/Cczu6a9y0V+VPOVEC9RPvVrjyDyXHhDT5r9STY
Tsd3Et1VaImvzzYMmS2xv4zyUt/j3eAqMpYK1VwdlR54so3qFhIC7B36wzYglIUd
6l9pPXgpY4SIQ9chITBv7BAoryAvVpbdJmhgocBjfQKBgHaA5x1ZYo+yzCmFd5Rs
D2tUzydxwe5jmuPoBRm0dUfePw3C37AjNwU34A9Ba9EHYOMw7lekWIzi8KBROIei
M1d1LfoKEyF2CoLGaOmrbAkfLofbRLrVXY0J9+KB4Q87caVGccUq3BQ9Y9GPiPLU
iJLCUjqopxEqMt+Z4GJDNzsF
-----END PRIVATE KEY-----

Am I missing something? How can I produce the same key output as commandline_fred.key? Based on this post, my confusion is between PKCS#8 and PKCS#1. The PKI::PKI.save.key function produces the RSA private key (PKCS#1). Can the R openssl package do the same?

jeroen commented 7 years ago

This is an entirely different issue. RSA keys can be stored in either the very old PKCS#1 format, and the standard PKCS#8 format. Unfortunately they are indistinguishable from the PEM encoding.

I am guessing you run a very old version of the openssl command, because current versions use PKCS#8. Note that openssl < 1.0.1 is deprecated and considered insecure.

openssl version

To make the output of the openssl command line match that of the R package, try running your command with a more current version of openssl. On MacOS:

brew install openssl
/usr/local/opt/openssl/bin/openssl pkcs12 -nomacver -nocerts -nodes -in fred.p12

This should give the same output as the R package. Everyone nowadays uses PKCS#8 because it also supports other types of keys (EC, DSA) whereas PKCS#1 was limited to RSA.