RSA encryption using client keys


#1

Hi all,

I don’t like the encrypted data bags since those require an additional secret
on the nodes that need to decrypt the data bag and since there is already an
existing PKI I implemented RSA en/decryption:

  • I run a script[1] (will try to convert that into a knife plugin asap) on my
    workstation that takes two arguments: client name and the secret to be
    encrypted. This will retrieve the public key of the client from the Chef server
    and use it to encrypt the secret to encrypted_string.
  • I use that string as the value for node[:my_new_cookbook][:ciphertext_secret]
  • In the cookbook I call a ruby script[2] that does the following things:
    a) takes the value of the attribute
    node[:my_new_cookbook][:ciphertext_secret] as an argument
    b) use the private key in /etc/chef/client.pem to decrypt it, and store it
    in /tmp/cryptofoo
  • then I can use the decrypted password by accessing /tmp/cryptofoo

Obviously using an external ruby script sucks and this is the reason I am
posting here:

Should I put the decryption functionality into a library inside e.g. the
OpenSSL cookbook and consequently include that library in any recipes that
needs that feature or rather make it a resource/provider?

I think a knife plugin with a syntax like
knife node secret <node/client-name>
would be pretty nice.

If I am totally off here, please let me know :slight_smile:

Cheers,

Oscar

[1]
#!/usr/bin/ruby1.8
require 'openssl’
require 'chef’
require 'json’
require ‘base64’

clientname = ARGV[0]
string = ARGV[1]

pubkey_string = JSON::parse(knife client show #{clientname} -f json).public_key

I need an OpenSSL::PKey object to encrypt, therefore need to convert the

string
public_key = OpenSSL::PKey::RSA.new pubkey_string
encrypted_string = Base64.encode64(public_key.public_encrypt(string))

puts encrypted_string

[2]
#!/usr/bin/ruby1.8
require 'json’
require 'base64’
require ‘openssl’

encrypted_string = ARGV[0]

private_key = OpenSSL::PKey::RSA.new(File.read("/etc/chef/client.pem"))
string = private_key.private_decrypt(Base64.decode64(encrypted_string))
out = File.open(’/tmp/cryptofoo’, ‘w’)
out.write string
out.close