Home > Enterprise >  Rails 7 - how to export RSA 2048 key pair to env credentials
Rails 7 - how to export RSA 2048 key pair to env credentials

Time:11-09

I'm super fresh in Rails and today I discovered RSA 2048 key. To generate such a key I used ruby-jwe gem. Creating such a key and testing it is trivial, rails console based on docs:

> key = OpenSSL::PKey::RSA.generate(2048)
 => #<OpenSSL::PKey::RSA:0x0000000113d6e368 oid=rsaEncryption>
> puts key
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEArXPkbAkge5WBhMZsWqgu2wbk0h81uhRUJHZsixtnb fc2j04
E93e9cTHT/EBQDMO5yR26ctK t0kAJ7CIivcqscnD3wBm7R07Nux93MwzjBRO Pb
YqQquES 2csLAHuCK0k/ME2Do1UxOMtTbO3FKpJWRaSaDYUL2UrIc2UPTfpPuGkd
XbPHpATLwkhp0/oq2Vrja87gJynxKjFMsepAF pMa8k37THS3uaJjZdLsVVpPJHe
JAbnIR3EW6veflYOzd5lJQOota9Dg5EKNEeIZrZKyOktPojLd2ebD9vQI0dbidFP
nunfCvBtXjcL4Ua8eJzwMYUUrttLPVR71L7SmwIDAQABAoIBAQCev3vm O92zF2O
9L/EtTq1EXkpapEUrnhYKt6q7jjcLbxvLSp 3EisbR3x52S6qkBQgoom7f3A3daO
jr6k4boDv2PbgyZBqIZ/JY bJx0bCRPAGYn3nMLQhXKbCH8YQPHgxhgEEF2ThmwX
S9gd0PvsO6Sj9sNb7lHq3Mva TpppVRlx gA pk8yeJtJ4rjdcJwzNDZVosrQRgb
0CBNVKe6VO3Xa71ilLnpM295xUYs733FMMvu5gi6Vsq7rFrODH5AElvsOYFt2Kp 
m0ehDjRM wx FZSfi6R39b8XxK7yL8Qa7r0YRLFEOkdyZw74LW0YO1/ vzlbCcD8
ZUS1ULoxAoGBAOVonyQ5x0HRO6YkSf4LIWm3Ecl4rGNMHcdP/MPfMYaq5Xv51iFg
m3Wk3RFCgvB20PzM4LquPnEKrcZZk5pR9OVcKcNK7yDKEWiObLGmEbc4G9IcSBYu
/0l9trZRcNF2NcrVKYAqx6AiriUyUPDTGQorMWyszCe3ok4jvAtP04E5AoGBAMGO
2y2ye1AJQgdzXXCSwV25ofVvqk bY47iojAaFUE0UdRzh8/xJUoaHoiwrBbCmI6c
ls3nmkqcrV7Kw4oyb0DspKyURUpORpXvHLsTtuxTavdg4DpmO3VaLVpdKvec783S
GwIhzxKUeJtNED8bOEnep4RP0KjfZNAFQdzCB/ZzAoGBAJPdpYXx/ 76cBocldy7
S QZ7csQjvzJ2P/ZHLEbsY59pMEOPejxngJsK1mupztbOkVXwRpSqUive2a34h27
6b/Ucc7BA/T8ic/8zS6MPir8bWI2fHhf/oheEWDeiXtZWD7Oupsz98vNzrWHAwjW
5/LX Fl133lSMblv6wrXfxpxAoGBAMDVni8svgXC83GQ0eqxisvhgSWQllCxMsLL
r2HU2pAXm97ZKtlUGh51Xy43NXuHa43JG8UPlHv5FBB4Wc9457X7DSSSo2WgDlqZ
2jnXLkrL4KmMblhAOcR0jvKUF5aRV6fqRtYc8LxGBtJSOHlmmPGfTa1YBz33Mey9
EBzrghtZAoGAf9rGx08UFdxbXbqZMTuG3Nd8o0gBGQSi8aSRKDozg2cAMGFa22Gk
raiU9uVHaFCXtB30ioQtPnDqMNItFUDMeE1N73FNNNVwIgllUUbVUZjKZfLrRp0Z
p4SDTcHLDIWIBrA J5k8EXdldnskZcVWGSgITdIl42AdWngcCGWExCI=
-----END RSA PRIVATE KEY-----
 => nil

But now I want to add this key to the Rail env secrets (I'm using Rails 7 so multi environment credentials) to fetch this as Rails.application.credentials.rsa_key.

I thought all I need to do would be copy/paste that key into e.g. development.yml.enc like below:

`EDITOR=vim rails credentials:edit --environment development`
    
rsa_key: '-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEArXPkbAkge5WBhMZsWqgu2wbk0h81uhRUJHZsixtnb fc2j04
E93e9cTHT/EBQDMO5yR26ctK t0kAJ7CIivcqscnD3wBm7R07Nux93MwzjBRO Pb
YqQquES 2csLAHuCK0k/ME2Do1UxOMtTbO3FKpJWRaSaDYUL2UrIc2UPTfpPuGkd
XbPHpATLwkhp0/oq2Vrja87gJynxKjFMsepAF pMa8k37THS3uaJjZdLsVVpPJHe
JAbnIR3EW6veflYOzd5lJQOota9Dg5EKNEeIZrZKyOktPojLd2ebD9vQI0dbidFP
nunfCvBtXjcL4Ua8eJzwMYUUrttLPVR71L7SmwIDAQABAoIBAQCev3vm O92zF2O
9L/EtTq1EXkpapEUrnhYKt6q7jjcLbxvLSp 3EisbR3x52S6qkBQgoom7f3A3daO
jr6k4boDv2PbgyZBqIZ/JY bJx0bCRPAGYn3nMLQhXKbCH8YQPHgxhgEEF2ThmwX
S9gd0PvsO6Sj9sNb7lHq3Mva TpppVRlx gA pk8yeJtJ4rjdcJwzNDZVosrQRgb
0CBNVKe6VO3Xa71ilLnpM295xUYs733FMMvu5gi6Vsq7rFrODH5AElvsOYFt2Kp 
m0ehDjRM wx FZSfi6R39b8XxK7yL8Qa7r0YRLFEOkdyZw74LW0YO1/ vzlbCcD8
ZUS1ULoxAoGBAOVonyQ5x0HRO6YkSf4LIWm3Ecl4rGNMHcdP/MPfMYaq5Xv51iFg
m3Wk3RFCgvB20PzM4LquPnEKrcZZk5pR9OVcKcNK7yDKEWiObLGmEbc4G9IcSBYu
/0l9trZRcNF2NcrVKYAqx6AiriUyUPDTGQorMWyszCe3ok4jvAtP04E5AoGBAMGO
2y2ye1AJQgdzXXCSwV25ofVvqk bY47iojAaFUE0UdRzh8/xJUoaHoiwrBbCmI6c
ls3nmkqcrV7Kw4oyb0DspKyURUpORpXvHLsTtuxTavdg4DpmO3VaLVpdKvec783S
GwIhzxKUeJtNED8bOEnep4RP0KjfZNAFQdzCB/ZzAoGBAJPdpYXx/ 76cBocldy7
S QZ7csQjvzJ2P/ZHLEbsY59pMEOPejxngJsK1mupztbOkVXwRpSqUive2a34h27
6b/Ucc7BA/T8ic/8zS6MPir8bWI2fHhf/oheEWDeiXtZWD7Oupsz98vNzrWHAwjW
5/LX Fl133lSMblv6wrXfxpxAoGBAMDVni8svgXC83GQ0eqxisvhgSWQllCxMsLL
r2HU2pAXm97ZKtlUGh51Xy43NXuHa43JG8UPlHv5FBB4Wc9457X7DSSSo2WgDlqZ
2jnXLkrL4KmMblhAOcR0jvKUF5aRV6fqRtYc8LxGBtJSOHlmmPGfTa1YBz33Mey9
EBzrghtZAoGAf9rGx08UFdxbXbqZMTuG3Nd8o0gBGQSi8aSRKDozg2cAMGFa22Gk
raiU9uVHaFCXtB30ioQtPnDqMNItFUDMeE1N73FNNNVwIgllUUbVUZjKZfLrRp0Z
p4SDTcHLDIWIBrA J5k8EXdldnskZcVWGSgITdIl42AdWngcCGWExCI=
-----END RSA PRIVATE KEY-----'

But turn out those two are not the same because after some test I'm getting an error:

> encrypted = JWE.encrypt(payload, key)
 => "eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkExMjhHQ00ifQ.miYseR0y6hAFFzb8KzwbUKxp3deqP7Q2uMM2A1ylOVKH4wHIsbPu3WJxqX_C75jplt4HwTN32ERLwqUrl_KMUn-5wuVgBi1CkUiuh83DDms0u-xx9eaLvYnlMWGtH_T_D8Ffbe2BT--6DWpmP_...

> plaintext = JWE.decrypt(encrypted, Rails.application.credentials.rsa_key)
`decrypt': undefined method `private_decrypt' for "-----BEGIN RSA PRIVATE KEY----- MIIEpQIBAAKCAQEArXPkbAkge5WBhMZsWqgu2wbk0h81uhRUJHZsixtnb fc2j04 E93e9cTHT/EBQDMO5yR26ctK t0kAJ7CIivcqscnD3wBm7R07Nux93MwzjBRO Pb (...)

Why such storage is impossible?

CodePudding user response:

It is because you are passing a string to JWE.decrypt instead of a key (an instance of OpenSSL::PKey::RSA).

Refer to the following code:

require 'openssl'
require 'jwe'

key = OpenSSL::PKey::RSA.generate(2048)
encrypted = JWE.encrypt("hello there", key)

key_string = key.to_s

# What you are doing:
# plaintext = JWE.decrypt(encrypted, key_string)

# What you need to do:
plaintext = JWE.decrypt(encrypted, OpenSSL::PKey::RSA.new(key_string))
p plaintext

You can take the string you are storing with Rails credentials and instantiate a new OpenSSL::PKey::RSA from it.

It is important to store your key correctly in the YAML. Make sure that it includes the "-----BEGIN " line. Also use the pipe and indentation to ensure the newlines are preserved, like so:

rsa_key: |
  -----BEGIN RSA PRIVATE KEY-----
  MIIEpAIBAAKCAQEAwX91sW499nMLbDEdk4RFlxatc/WbDMeDNH01cboqKoUHK32r
  aqfmDLGGgDdBZpIO 1w7un 9Vg/uP6UsYqFsct2o60rCFZh4QXOXfhUwlfwEUlus
  4AqYZQtSvztiDNq1pDd3lrwdLVWbYQIyvI/gSK1hBFbb8tOZ8j18SYLucqjo8GWQ
  DqC rkHMHQtVWRmwVjVFA1MFj5AEfhaVNOYxnlQeKs07Iny0NGZV7vWcj fx4zRr
  Xxi2OHKmVHldzUhCwcjWNGzI8ORYo3ko1 KhVy091BV2ovKTixG7w6ZyX8rYt ob
  ZTgCJKjia/RpOjt/b5QvfDDLmRRZZUSOwB625QIDAQABAoIBABW8HPrAsNoZgxt0
  iudykKSPig0/9doiIQVI2TN8n1bmWW9TrukMkgUz/bEyQ7jjSCaI7jadOaXMpUzl
  30325ukiJ LCI3nshfmII ioNaxrQgsEPC9wUTzsYC V2oYqHQQkrNy0JazddFYZ
  upw pwlS3FZx8UPd6 lvaaISQHmFeH0FFIyGLcnyvuzaLqHVy9 3fpr3F1hp2qPg
  H04QDTjkpG0XK vNDXx4NrVndVOQ3GM94vPNmF60E j 7YeV0LzAdhGrQQ3zjBic
  BsDg5ZoYFOdqL3nluza58Vb0n7ZZrGeMh7sTthjEMI5Px//XcvBN2bJQLIaBP/My
  QIPjdwECgYEAzosh60KFBk6RtRWK4ZjNiTlbCUQuDEThJidXtTnOmYP3e1u1rkZP
  kPJ5eu1H4dsmDppmBM4p368Y8U9Di2mQO3zo Q32Kl6On6aExuvgqfFG7wS6GGtP
   JUvI7cl19Tn2BZEisAx7nYtCYPMRtXNXZaHPTbcw/XDgEuEgDXBAoECgYEA79Sl
  2PCHGJxRWTQmWWzs9wSIFRhWOPcuHDs2LveM0AGtCxNEGObsQQZLrqD/M0oTsuh3
  8SPXKtJu2L/og9THi2EAPwEInd50dmeotzrE3dIqthxdO3lESkzV/Er14NeWjphC
  dmKoG31NHXvw5mZ3Y C1Ya W376EoV/rki2numUCgYB6GCsb3D2wpb9icXKgu2g8
  xyf2iVRDMnB50mX5nktv2l/wjx0OAUhFoeCH9z432AleNo06J/j 3o37D UYw3Vc
  hRFfMI6lKzJaU BHiuZK73MEFiJADye BcpQ7ZI0TQokZb1s3AJoOXmUF1IpSXfV
  7AbT 9tzB5PjAkE4XQ5UgQKBgQCRVuj6wyjbvT9/M59Z6izgtZpSTmFSPFlxOmDn
  rZVkKN/ZKl/GR4s9DLeoqGB/kJDHhyHIvNOUW9pY FPMMJKM4MfpZpL2OO2TI9aW
  08KiOs8vdZj6hc7gyBeVwUeobn4LBDKi077UiebFy2p99fK8UF0bSfHAvhBaS2rT
  N1/CEQKBgQDGpl0oYWNkzkU9iTg1ncSHmzJLuk08ooHIEoS0AtyCRe5PLk0AX/f2
  DsrgrFWwXmTlt9L49hG1E hc6Zst3t y GR9sDjXVnIBkwNtDWs 8cZSwwxS fxq
  A4uqx0/DrZ/Dx7Yukf74vOjghZpott/Q77MUVsHy28N9IAt3iL V3w==
  -----END RSA PRIVATE KEY-----

Now you can use this in a Rails console like this:

key = OpenSSL::PKey::RSA.new(Rails.application.credentials.rsa_key)
encrypted = JWE.encrypt("hello there", key)

plaintext = JWE.decrypt(encrypted, key)
p plaintext  # => "hello there"
  • Related