ex_crypto
ex_crypto copied to clipboard
problem with AES-256-CBC private key
Hi there, I've found your very useful Elixir lib but I'm facing with an issue when I'm using AES-256-CBC private keys
Test case that fails: test/ex_public_key_test.exs insert at line : 32 "-aes256",
so instead of
# generate a passphrase protected RSA private key with openssl
System.cmd("openssl", [
"genrsa",
"-out",
rsa_secure_private_key_path,
"-passout",
"pass:#{rand_string}",
"2048"
])
we have now
# generate a passphrase protected RSA private key with openssl
System.cmd("openssl", [
"genrsa",
"-aes256",
"-out",
rsa_secure_private_key_path,
"-passout",
"pass:#{rand_string}",
"2048"
])
and the test mix test test/ex_public_key_test.exs:79 fails
1) test read secure RSA keys (ExPublicKeyTest)
test/ex_public_key_test.exs:79
** (CaseClauseError) no case clause matching: {:error, %FunctionClauseError{args: nil, arity: 4, clauses: nil, function: :decode, kind: nil, module: :pubkey_pbe}, [{:pubkey_pbe, :decode, [<<43, 180, 39, 134, 179, 160, 115, 204, 207, 162, 100, 17, 226, 84, 197, 254, 3, 10, 68, 212, 144, 49, 120, 150, 239, 201, 223, 214, 213, 157, 39, 151, 17, 109, 42, 106, 193, 217, 176, 117, 244, 187, ...>>, 'KLvk', 'AES-256-CBC', <<246, 36, 62, 81, 225, 191, 64, 102, 55, 197, 38, 121, 69, 244, 140, 46>>], [file: 'pubkey_pbe.erl', line: 59]}, {:public_key, :do_pem_entry_decode, 2, [file: 'public_key.erl', line: 1103]}, {ExPublicKey, :load_pem_entry, 2, [file: 'lib/ex_public_key.ex', line: 128]}, {ExPublicKey, :load_pem_entry, 2, [file: 'lib/ex_public_key.ex', line: 122]}, {ExPublicKey, :loads, 2, [file: 'lib/ex_public_key.ex', line: 94]}, {ExPublicKey, :loads!, 2, [file: 'lib/ex_public_key.ex', line: 107]}, {ExPublicKeyTest, :"test read secure RSA keys", 1, [file: 'test/ex_public_key_test.exs', line: 81]}, {ExUnit.Runner, :exec_test, 1, [file: 'lib/ex_unit/runner.ex', line: 306]}, {:timer, :tc, 1, [file: 'timer.erl', line: 166]}, {ExUnit.Runner, :"-spawn_test/3-fun-1-", 4, [file: 'lib/ex_unit/runner.ex', line: 245]}]}
code: secure_rsa_priv_key = ExPublicKey.loads!(secure_priv_key_string, context[:passphrase])
stacktrace:
(ex_crypto) lib/ex_public_key.ex:107: ExPublicKey.loads!/2
test/ex_public_key_test.exs:81: (test)
if you replace "-aes256" with "-aes128" . test/ex_public_key_test.exs is OK
Any idea? Many thanks in advance Daniel
Interesting, what versions of Elixir, Erlang, and OpenSSL are you using?
Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Elixir 1.6.0 (compiled with OTP 20)
Erlang : 20.2.2
LibreSSL 2.2.7
Does the openssl
command run on your system with the same arguments and not produce the error?
openssl genrsa -aes256 -out rsa_secure_private.pem -passout pass:123456 2048 openssl rsa -in rsa_secure_private.pem Enter pass phrase for rsa_secure_private.pem: writing RSA key -----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEA0HZ70HME/G38kS9axeSqlSk3V9EnJHCbN/f0PLLR1wrjKmtr 7+C1odMb2MuuiF4IKn9mHwH6PvDRNZHtMlbeqKSo/bLlWPySlj7arZHIEA00BFi8 lRr2APn8JRgF39WFr1xxudpCrNP0TtlJAKESAusXum9IUCYGbmuPiatx2SezaOMX Uag/ESZabs0yZWSWaBZWbABfBprkMGaOYpFLbLKioESXt+utcAkuzPTdJ9CuajgX q5bYV2gL2+fsu+G6a65hpafRRLWjkjCpQZBPUCf6xoRtdUCBoy3ecT7zkYmn7b3u HNtpSpBFCwMLruwrXoPj0d0NBilKoIsctsBquQIDAQABAoIBABIj7VxTVgC9dXgQ 3d5QqsN2Jbm/mp9iKS+ypQ9PJFGJQgFj/a2PKV8eptKzzslRHXbNRU63dlZZ0GrP +wshYhjc01PYaHrY58ypRZBLGlTDQV6LdkWnZfbpyhZUQ9aZlxuOeNsKcjjl7OGb qO2kFpQobxUrL+jBllevhnsdbzfNQ2WGTEn+Va1woX+cFyZD5Fw6PtPlKBZF7HMv DK6Lvbx30QOv3w6bgwQtVpqSt9i9B1Vy2vVc+FgJbCKnRMiryz0n9/BBK2xomSp3 k0um/hSRtYIq1GDiYQjipp9wl2TGG0reAAOAvatPhze8APZX1+fJ0OZVOoMeqYt/ XHTMkv0CgYEA70CGc17CLmnGNDxliqZVkSGLPTJ4beFbZuOZXS8VZCEFvps0ztnW QKiSf/KOxmi/R4dR3DrasIX5QaVH+TkEJ/5ga4wg076dLj1rmuz5QfqGc31bAo9L RyRBRSWD7Ti8eEXDd41NOeI4Du6pA5fZPU1qV0LGDROKEUxY9kevx5MCgYEA3w40 m60dHQIgaPr8Yda2j9dqr7rmnOpDireGOrDWylVBuEaPMKxpSzdmZfU6TbbnYgRV OTskIX0NdqwUjWRnsss/R0sUW/GO2UuURc12VxsyBYSrQYYWLi83UMvsRm511HGP aLZlJjP+2/ZpLDW92tN67TKRjYLL5zhp/mLPHAMCgYAr+NL9L0RHHX+lKBiNhAaj 9uNNaxJBN7MB1QDh5H5s+bjBkGsDPXwoRBMw2tas1qGZNuCvtk1tNiJak1MIFheS dikoewepgxYGYpl9TuJ84tuFLFvmu4ldWOd6GuwFVHEnNcM4HMs9wTsGW4zKsUTn BGxv/0DBNH8isMKE+SXwawKBgDGcBzdYmVEKWAsBR4C7MH9tedz7xK7Bq6P+jWwg SKVXsPY7Oz2oGwMPn0at8/m05GF4dTv1W2PXXFc4jpmj6yxo5/oDSNPqNcs+dAvS Vq+o7Mctaql4GRbMiZD+yd4gUzSczTiM2JJWniht9ZZPnZo9zulShezjWlZixbA+ abHhAoGAWIf74mddVbgMhZC6Cql6dGu71NBnM4JpbLmRVUqa38iYCu5tiSdhib1r 7uIlKYNeTpZipr7tzROIxGrNtx4ggY6UeYoo5UOmL68fHK9j4f7oWK8KlgsCmbFE 6BtZJcltYUcP3A6fb1F9rpjsyPOfYEukT74iXm/EU9HWQPR4dvc= -----END RSA PRIVATE KEY-----
I have an idea what might be going on, I'll check and see, then post back here.
I think this may be a limitation of the underlying public_key
Erlang library. We use this function to decode the PEM entry for the encrypted private key:
- http://erlang.org/doc/man/public_key.html#pem_entry_decode-2
I don't see a way to pass it any options to let it know the pem_entry
argument is encrypted using AES256. If we wanted to support that option we might need to write a step to decrypt the key first and then pass it in the clear to :public_key.pem_entry_decode/1
.
Is that something you would want to take a crack at in a pull-request? If not I might have some time to tackle it in the next week or so.
I'm not an Erlang specialist and this is not blocking me at the moment, so I can wait.
It seems that Erlang implements PKCS#5 v2.0 against RFC-2898. Support for AES-256-CBC was added later in RFC-8018 v2.1.
I don't know exactly at what points they differ but I'm quite sure the Erlang team will take some time to implement it.
So, at this point, I think there's nothing we can do.