Per the Dovecot site here: https://wiki.dovecot.org/Plugins/MailCrypt ... the "decrypt.rb" ruby script can be used to decrypt a Dovecot-encrypted message file from the command line. The script sort of runs successfully for me, in the sense that it doesn't error out, but it doesn't show the decrypted message.
I've called it like so: decrypt.rb -k <PATH_TO_DOVECOT_KEYFILE> -f ./encrypted_message
But when I do it just displays the info below and exits (I've subbed <DATA> tags for the actual data):
------------------[OUTPUT]-----------------------
Key(s) (total: 1) - Key type : EC - Key digest: <DATA1> - Peer key : <DATA2> - Encrypted : <DATA3> - Kd hash : <DATA4>
I've tried specifying an output file as well, per the script's command line options, but the output file is 0 bytes. Does anyone have any suggestions? I *think* I'm using it the way it's intended to be used, but maybe I'm not?!
-Dave
On 9.4.2019 2.33, Dave via dovecot wrote:
Per the Dovecot site here: https://wiki.dovecot.org/Plugins/MailCrypt ... the "decrypt.rb" ruby script can be used to decrypt a Dovecot-encrypted message file from the command line. The script sort of runs successfully for me, in the sense that it doesn't error out, but it doesn't show the decrypted message.
I've called it like so: decrypt.rb -k <PATH_TO_DOVECOT_KEYFILE> -f ./encrypted_message
But when I do it just displays the info below and exits (I've subbed <DATA> tags for the actual data):
------------------[OUTPUT]-----------------------
Key(s) (total: 1) - Key type : EC - Key digest: <DATA1> - Peer key : <DATA2> - Encrypted : <DATA3> - Kd hash : <DATA4>
I've tried specifying an output file as well, per the script's command line options, but the output file is 0 bytes. Does anyone have any suggestions? I *think* I'm using it the way it's intended to be used, but maybe I'm not?!
-Dave
Hi!
Maybe the key you tried was not used to encrypt the file?
Aki
I've tried specifying an output file as well, per the script's command line options, but the output file is 0 bytes. Does anyone have any suggestions? I *think* I'm using it the way it's intended to be used, but maybe I'm not?! -Dave
Hi! Maybe the key you tried was not used to encrypt the file? Aki
Aki, it's the same key I've used in the config for the mail_crypt plugin in 90-plugin.conf:
plugin { mail_crypt_global_private_key = <[PATH_TO_PRIVATE_KEY] mail_crypt_global_public_key = <[PATH_TO_PUBLIC_KEY] mail_crypt_save_version = 2 }
That's the private key that's encrypting all of the messages successfully, so that's the one I would use with script, correct? -Dave
On 9.4.2019 18.15, Dave wrote:
I've tried specifying an output file as well, per the script's command line options, but the output file is 0 bytes. Does anyone have any suggestions? I *think* I'm using it the way it's intended to be used, but maybe I'm not?! -Dave
Hi! Maybe the key you tried was not used to encrypt the file? Aki
Aki, it's the same key I've used in the config for the mail_crypt plugin in 90-plugin.conf:
plugin { mail_crypt_global_private_key = <[PATH_TO_PRIVATE_KEY] mail_crypt_global_public_key = <[PATH_TO_PUBLIC_KEY] mail_crypt_save_version = 2 }
That's the private key that's encrypting all of the messages successfully, so that's the one I would use with script, correct? -Dave
Yes. I gave it a try here, and it seems to work. Does it give any extra information if you include -i flag?
Aki
On 4/10/2019 1:32 AM, Aki Tuomi wrote:
On 9.4.2019 18.15, Dave wrote:
I've tried specifying an output file as well, per the script's command line options, but the output file is 0 bytes. Does anyone have any suggestions? I *think* I'm using it the way it's intended to be used, but maybe I'm not?! -Dave Hi! Maybe the key you tried was not used to encrypt the file? Aki Aki, it's the same key I've used in the config for the mail_crypt plugin in 90-plugin.conf:
plugin { mail_crypt_global_private_key = <[PATH_TO_PRIVATE_KEY] mail_crypt_global_public_key = <[PATH_TO_PUBLIC_KEY] mail_crypt_save_version = 2 }
That's the private key that's encrypting all of the messages successfully, so that's the one I would use with script, correct? -Dave
Yes. I gave it a try here, and it seems to work. Does it give any extra information if you include -i flag?
Aki
Yes, I had tried that, and it doesn't give much extra information, at least to my eye, that seems to help my issue. Above the previous output it outputs the Version, Flags, Header length, Cipher algo, and Digest algo, and then the Key derivation Rounds. Then it does the previous output and exits as before.
I tried using pry to debug through the script a little, and strace as well, but have not found anything pointing me in the direction of a solution or what may be causing it not to work for me yet. Will keep looking.
Out of curiosity, what version of ruby were you using to run the script? My ruby version is 2.5.1p57.
-Dave
Yes. I gave it a try here, and it seems to work. Does it give any extra information if you include -i flag?
Aki
Yes, I had tried that, and it doesn't give much extra information, at least to my eye, that seems to help my issue. Above the previous output it outputs the Version, Flags, Header length, Cipher algo, and Digest algo, and then the Key derivation Rounds. Then it does the previous output and exits as before.
I tried using pry to debug through the script a little, and strace as well, but have not found anything pointing me in the direction of a solution or what may be causing it not to work for me yet. Will keep looking.
Out of curiosity, what version of ruby were you using to run the script? My ruby version is 2.5.1p57.
-Dave
So, I found that in decrypt.rb there is a point where this section is reached:
[code] unless our_key == nil # decrypt data! [/code]
While testing I discovered that, for me, our_key was apparently equal to nil because the code was never even making it into that block. There was a block right above that that was setting our_key to nil if a certain condition happened, but I could tell that condition wasn't happening as the accompanying error message wasn't printing. Looking farther up, I found:
[code] our_key = key if key[:digest] == options[:key_digest] [/code]
I printed the values of key[:digest] and options[:key_digest], and they are in fact different. Since our_key is nil by default, our_key was just remaining nil, hence no decryption for me.
The key[:digest] variable is filled a little above that part of the code:
[code] (key[:type],key[:digest]) = options[:input].read(33).unpack('Ca*') [/code]
and options[:key_digest] is filled as the private key option is passed in:
[code] opts.on("-k","--key KEY", "Private key to decrypt file") do |k| options[:key] = OpenSSL::PKey.read(File.open(k)) options[:key_digest] = get_pubid_priv(options[:key]) end [/code]
It's apparently using the key from the command line to get the key digest with the get_pubid_priv() function, and for some reason that value is coming back as different than the key digest that is ascertained by the "options[:input].read" line.
Out of curiosity, and since I know I'm using the correct key, I commented out the if statement in the our_key line so as not to make the comparison between the digests:
[code] our_key = key #if key[:digest] == options[:key_digest] [/code]
.... and then it worked! The script successfully decrypted the message!
So, not being an expert at encryption, what are the ramifications of those digests being read as different values in the two different places?? I do notice that the get_pubid_priv() function is internal to the decrypt.rb script and calls several OpenSSL functions.
-Dave
On 11 April 2019 00:49 David Salisbury via dovecot <dovecot@dovecot.org> wrote:
Yes. I gave it a try here, and it seems to work. Does it give any extra information if you include -i flag?
Aki
Yes, I had tried that, and it doesn't give much extra information, at least to my eye, that seems to help my issue. Above the previous output it outputs the Version, Flags, Header length, Cipher algo, and Digest algo, and then the Key derivation Rounds. Then it does the previous output and exits as before.
I tried using pry to debug through the script a little, and strace as well, but have not found anything pointing me in the direction of a solution or what may be causing it not to work for me yet. Will keep looking.
Out of curiosity, what version of ruby were you using to run the script? My ruby version is 2.5.1p57.
-Dave
So, I found that in decrypt.rb there is a point where this section is reached:
[code] unless our_key == nil # decrypt data! [/code]
While testing I discovered that, for me, our_key was apparently equal to nil because the code was never even making it into that block. There was a block right above that that was setting our_key to nil if a certain condition happened, but I could tell that condition wasn't happening as the accompanying error message wasn't printing. Looking farther up, I found:
[code] our_key = key if key[:digest] == options[:key_digest] [/code]
I printed the values of key[:digest] and options[:key_digest], and they are in fact different. Since our_key is nil by default, our_key was just remaining nil, hence no decryption for me.
The key[:digest] variable is filled a little above that part of the code:
[code] (key[:type],key[:digest]) = options[:input].read(33).unpack('Ca*') [/code]
and options[:key_digest] is filled as the private key option is passed in:
[code] opts.on("-k","--key KEY", "Private key to decrypt file") do |k| options[:key] = OpenSSL::PKey.read(File.open(k)) options[:key_digest] = get_pubid_priv(options[:key]) end [/code]
It's apparently using the key from the command line to get the key digest with the get_pubid_priv() function, and for some reason that value is coming back as different than the key digest that is ascertained by the "options[:input].read" line.
Out of curiosity, and since I know I'm using the correct key, I commented out the if statement in the our_key line so as not to make the comparison between the digests:
[code] our_key = key #if key[:digest] == options[:key_digest] [/code]
.... and then it worked! The script successfully decrypted the message!
So, not being an expert at encryption, what are the ramifications of those digests being read as different values in the two different places?? I do notice that the get_pubid_priv() function is internal to the decrypt.rb script and calls several OpenSSL functions.
-Dave
Hmm... can you show me how you made the keypair for encryption? Maybe there is some difference?
Aki
On 4/11/2019 1:50 AM, Aki Tuomi wrote:
... So, not being an expert at encryption, what are the ramifications of those digests being read as different values in the two different places?? I do notice that the get_pubid_priv() function is internal to the decrypt.rb script and calls several OpenSSL functions.
-Dave Hmm... can you show me how you made the keypair for encryption? Maybe there is some difference?
Aki
Aki, I just used the "EC key" instructions from the Dovecot MailCrypt wiki: https://wiki.dovecot.org/Plugins/MailCrypt
" In order to generate an EC key, you must first choose a curve from the output of this command:
openssl ecparam -list_curves
If you choose the curve prime256v1, generate and EC key with the command:
openssl ecparam -name prime256v1 -genkey | openssl pkey -out ecprivkey.pem
Then generate a public key out of your private EC key
openssl pkey -in ecprivkey.pem -pubout -out ecpubkey.pem "
-Dave
On 11 April 2019 17:44 David Salisbury via dovecot <dovecot@dovecot.org> wrote:
On 4/11/2019 1:50 AM, Aki Tuomi wrote:
... So, not being an expert at encryption, what are the ramifications of those digests being read as different values in the two different places?? I do notice that the get_pubid_priv() function is internal to the decrypt.rb script and calls several OpenSSL functions.
-Dave Hmm... can you show me how you made the keypair for encryption? Maybe there is some difference?
Aki
Aki, I just used the "EC key" instructions from the Dovecot MailCrypt wiki: https://wiki.dovecot.org/Plugins/MailCrypt
" In order to generate an EC key, you must first choose a curve from the output of this command:
openssl ecparam -list_curves
If you choose the curve prime256v1, generate and EC key with the command:
openssl ecparam -name prime256v1 -genkey | openssl pkey -out ecprivkey.pem
Then generate a public key out of your private EC key
openssl pkey -in ecprivkey.pem -pubout -out ecpubkey.pem "
-Dave
I'm going on a limb and guess that there is something strange happening with ruby and openssl versions here.
The main point of the script is to show how the data can be decrypted, and can be used for small-scale data recovery as well.
Aki
Aki, I just used the "EC key" instructions from the Dovecot MailCrypt wiki: https://wiki.dovecot.org/Plugins/MailCrypt
" In order to generate an EC key, you must first choose a curve from the output of this command:
openssl ecparam -list_curves
If you choose the curve prime256v1, generate and EC key with the command:
openssl ecparam -name prime256v1 -genkey | openssl pkey -out ecprivkey.pem
Then generate a public key out of your private EC key
openssl pkey -in ecprivkey.pem -pubout -out ecpubkey.pem "
-Dave I'm going on a limb and guess that there is something strange happening with ruby and openssl versions here.
The main point of the script is to show how the data can be decrypted, and can be used for small-scale data recovery as well.
Aki
Copy that. I would agree that it seems to be something weird between OpenSSL and Ruby in this case. Since I'm able to get it to work in my specific instance, and since it doesn't seem systemic outside of my situation, I'd say -- specific problem solved! :) Thanks for your help. -Dave
Hi team,
regarding:
https://www.mail-archive.com/dovecot@dovecot.org/msg77000.html
I have the very same problem.
terve:/tmp #decrypt.rb -k /etc/dovecot/mailcrypt/ecpubkey.pem -f ./1681118363....terve.xy-space.de\,S\=3452\,W\=3515\:2\,S
Key(s) (total: 1) - Key type : EC - Key digest: a27b201cf7f59f... - Peer key : 04aaca0143208904deced2732aaa... - Encrypted : 4cde641bff16098b91bfaf66... - Kd hash : 9e229ec6c0... terve:/tmp #decrypt.rb -k /etc/dovecot/mailcrypt/ecprivkey.pem -f ./16811....terve.xy-space.de\,S\=3452\,W\=3515\:2\,S
Key(s) (total: 1) - Key type : EC - Key digest: a27b201cf7f59f978bb9b27947f60a9... - Peer key : 04aaca0143208904deced2732aaaf127... - Encrypted : 4cde641bff16098b91bfaf66c9... - Kd hash : 9e229ec6c09...
terve:/tmp #decrypt.rb -i -k /etc/dovecot/mailcrypt/ecprivkey.pem -f ./1681118...terve.xy-space.de\,S\=3452\,W\=3515\:2 \,S Version : 2 Flags : AEAD integrity Header length : 255 Cipher algo : aes-256-gcm (2.16.840.1.101.3.4.1.46) Digest algo : sha256 (2.16.840.1.101.3.4.2.1)
Key derivation - Rounds : 2048
...
N. B. Before posting I arbitrarily removed numbers from the output, maybe paranoid...
Environment:
openSuSE Linux server.
dovecot version 2.3.20
openssl version 1.1.1
ruby version 3.1.2p20
decrypt.rb version https://gist.github.com/cmouse/882f2e2a60c1e49b7d343f5a6a2721de
This is the way I generated the keys:
openssl ecparam -name prime256v1 -genkey | openssl pkey -out ecprivkey.pem openssl pkey -in ecprivkey.pem -pubout -out ecpubkey.pem
This is the 10-mailcrypt.conf:
mail_plugins = $mail_plugins mail_crypt
plugin { #fts_index_fs = crypt:set_prefix=fscrypt_index:posix:set_prefix=/tmp/fts mail_crypt_global_private_key = </etc/dovecot/mailcrypt/ecprivkey.pem mail_crypt_global_public_key = </etc/dovecot/mailcrypt/ecpubkey.pem mail_crypt_save_version = 2 }
Encryption of incoming (thanks to dovecot-lda), as well as outgoing mails works perfectly.
But for me it is more a feature than a bug, since now, even as root I am not able to decrypt users mails.
This serves plausible deniability.
But how can I make sure, that NOBODY ELSE can decrypt with this specific private key?
Is there ANY OTHER way to decrypt the mails besides the script?
Have a nice Monday, and THANKS for taking your time!
Martin, Cologne
P. S. Did you notice, that as an argument (-k) the results are the same, both with private and public key?
P.P.S. If i give the "-w" argument and a file name, the file remains empty, tried even that without success.
P.P.P.S. If I call the script with ruby version 2 it bails out...
Op 10 apr. 2023 om 18:40 heeft Martin Stenzel <stenzel@bw-host.de> het volgende geschreven:
Hi team,
regarding:
https://www.mail-archive.com/dovecot@dovecot.org/msg77000.html
I have the very same problem.
terve:/tmp # decrypt.rb -k /etc/dovecot/mailcrypt/ecpubkey.pem -f ./1681118363....terve.xy-space.de\,S\=3452\,W\=3515\:2\,S
Key(s) (total: 1)
- Key type : EC
- Key digest: a27b201cf7f59f...
- Peer key : 04aaca0143208904deced2732aaa...
- Encrypted : 4cde641bff16098b91bfaf66...
- Kd hash : 9e229ec6c0... terve:/tmp # decrypt.rb -k /etc/dovecot/mailcrypt/ecprivkey.pem -f ./16811....terve.xy-space.de\,S\=3452\,W\=3515\:2\,S
Key(s) (total: 1)
- Key type : EC
- Key digest: a27b201cf7f59f978bb9b27947f60a9...
- Peer key : 04aaca0143208904deced2732aaaf127...
- Encrypted : 4cde641bff16098b91bfaf66c9...
- Kd hash : 9e229ec6c09...
terve:/tmp # decrypt.rb -i -k /etc/dovecot/mailcrypt/ecprivkey.pem -f ./1681118...terve.xy-space.de\,S\=3452\,W\=3515\:2 \,S
Version : 2 Flags : AEAD integrity Header length : 255 Cipher algo : aes-256-gcm (2.16.840.1.101.3.4.1.46) Digest algo : sha256 (2.16.840.1.101.3.4.2.1)Key derivation
- Rounds : 2048
...
N. B. Before posting I arbitrarily removed numbers from the output, maybe paranoid...
Why?
Environment:
openSuSE Linux server.
dovecot version 2.3.20
openssl version 1.1.1
ruby version 3.1.2p20
decrypt.rb version https://gist.github.com/cmouse/882f2e2a60c1e49b7d343f5a6a2721de
This is the way I generated the keys:
openssl ecparam -name prime256v1 -genkey | openssl pkey -out ecprivkey.pem openssl pkey -in ecprivkey.pem -pubout -out ecpubkey.pem
This is the 10-mailcrypt.conf:
mail_plugins = $mail_plugins mail_crypt
plugin { #fts_index_fs = crypt:set_prefix=fscrypt_index:posix:set_prefix=/tmp/fts mail_crypt_global_private_key = </etc/dovecot/mailcrypt/ecprivkey.pem mail_crypt_global_public_key = </etc/dovecot/mailcrypt/ecpubkey.pem mail_crypt_save_version = 2 }
Encryption of incoming (thanks to dovecot-lda), as well as outgoing mails works perfectly.
But for me it is more a feature than a bug, since now, even as root I am not able to decrypt users mails.
This serves plausible deniability.
But how can I make sure, that NOBODY ELSE can decrypt with this specific private key?
Is there ANY OTHER way to decrypt the mails besides the script?
Have a nice Monday, and THANKS for taking your time!
Martin, Cologne
P. S. Did you notice, that as an argument (-k) the results are the same, both with private and public key?
P.P.S. If i give the "-w" argument and a file name, the file remains empty, tried even that without success.
P.P.P.S. If I call the script with ruby version 2 it bails out...
On 10/04/2023 15:37 EEST Martin Stenzel <stenzel@bw-host.de> wrote:
Hi team, regarding: https://www.mail-archive.com/dovecot@dovecot.org/msg77000.html
I have the very same problem.
<snip/>
Hi!
It seems that the ruby openssl module interface has changed slightly, I'll look into it. We might as well move it to https://github.com/dovecot/tools while at it.
For what it's worth, it works with ruby2.7 for me.
The reason it looks the same with -k pub and priv, is that the key does not match, so it just tells you what key to expect. I'll make the output bit more verbose about this too.
Aki
Have a nice Monday, and THANKS for taking your time!
Martin, Cologne
P. S. Did you notice, that as an argument (-k) the results are the same, both with private and public key? P.P.S. If i give the "-w" argument and a file name, the file remains empty, tried even that without success.
P.P.P.S. If I call the script with ruby version 2 it bails out...
On 11/04/2023 09:03 EEST Aki Tuomi <aki.tuomi@open-xchange.com> wrote:
On 10/04/2023 15:37 EEST Martin Stenzel <stenzel@bw-host.de> wrote:
Hi team, regarding: https://www.mail-archive.com/dovecot@dovecot.org/msg77000.html
I have the very same problem.
<snip/>
Hi!
It seems that the ruby openssl module interface has changed slightly, I'll look into it. We might as well move it to https://github.com/dovecot/tools while at it.
For what it's worth, it works with ruby2.7 for me.
The reason it looks the same with -k pub and priv, is that the key does not match, so it just tells you what key to expect. I'll make the output bit more verbose about this too.
Aki
Also, if you need to verify the key ID, you can use
doveadm dump -t dcrypt-key /path/to/priv.pem
to see that the key hash matches with what decrypt.rb provides as "key hash".
Aki
On 11/04/2023 09:09 EEST Aki Tuomi <aki.tuomi@open-xchange.com> wrote:
On 11/04/2023 09:03 EEST Aki Tuomi <aki.tuomi@open-xchange.com> wrote:
On 10/04/2023 15:37 EEST Martin Stenzel <stenzel@bw-host.de> wrote:
Hi team, regarding: https://www.mail-archive.com/dovecot@dovecot.org/msg77000.html
I have the very same problem.
<snip/>
Hi!
It seems that the ruby openssl module interface has changed slightly, I'll look into it. We might as well move it to https://github.com/dovecot/tools while at it.
For what it's worth, it works with ruby2.7 for me.
The reason it looks the same with -k pub and priv, is that the key does not match, so it just tells you what key to expect. I'll make the output bit more verbose about this too.
Aki
Also, if you need to verify the key ID, you can use
doveadm dump -t dcrypt-key /path/to/priv.pem
to see that the key hash matches with what decrypt.rb provides as "key hash".
Aki
Can you try if this
https://raw.githubusercontent.com/dovecot/tools/main/dcrypt-decrypt.rb
works for you now?
Aki
participants (5)
-
Aki Tuomi
-
Dave
-
David Salisbury
-
Martin Stenzel
-
William Edwards