1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
|
## Implemented features and fixes not present in the official Sylpheed release
- (fix)
PGP signature not verified properly when the message has no newline
at the end. https://sylpheed.sraoss.jp/redmine/issues/288
- (feature)
Make it possible to select "Show signature check result in a popup window"
only for bad signatures.
- (feature)
Support for encrypting and storing encrypted passwords using a master password.
Read bellow for more details!
## Master password
The master password feature is developed by Simeon Simeonov (sgs)
and is currently in an experimental state.
### Motivation
Currently Sylpheed is storing passwords in plain-text. One can always refrain
from storing passwords and let Sylpheed prompt for them, but the more accounts
one has, the more annoying this becomes.
The goal is to have the passwords stored in a secure way and let Sylpheed only
prompt for the master password.
### Security goals
- attacker (A) should not be able to derive the password from the digest.
- A should not be able to derive the master password even if she has
read and write access to the storage.
- A should not be able to determine the length of the encrypted password
even if she has read and write access to the storage.
- A should not be able to craft an edited password without obtaining the
master password.
- A should not be able to compromise the master password or force Sylpheed
to store decrypted passwords even if she has access to a running Sylpheed.
- a warning / prompt should be given if a user accidentally types in a "wrong"
master password before decryption is initiated.
### Usage in Sylpheed
- backup your Sylpheed profile (often $HOME/.sylpheed-2.0)!
- start Sylpheed and open "Configuration" -> "Common preferences..."!
- select the "Master password" tab, enable "Use master password" and
apply the changes!
- restart Sylpheed (exit and then start Sylpheed again)!
- you will be asked to type and verify a new master password.
- set your new passwords from the "Configuration" -> "Edit accounts..."!
- select "Automatically unload master password after session initialization"
for increased security and decreased convenience.
Note:
Sylpheed will automatically convert existing stored passwords, but it will not
touch your backups. You will have to remove all remnants of plain-text
passwords manually.
### Choice of cryptographic primitives
The primary concern when selecting cryptographic primitives was portability.
The desire was to go for primitives that are both strong and available in all
supported production distributions of OpenSSL and LibreSSL.
#### Cipher
When it comes to implementation, there are several advantages in using stream
cipher or a block cipher that behaves like a stream cipher when used in a
certain mode of operation. One is avoiding to deal with padding.
AES-256 operating in CFB was selected for these reasons.
ChaCha20 should be considered as a replacement in the future.
#### Hash-function
Hash-functions are used for:
- key derivation
- plain-text digest
Those operations do not have to use the same hash-function.
(See the "Encryption & decryption scheme" section for more details!)
Key-derivation:
Since AES-256 uses a 256 bits key, we need a hash-function with at least
the same digest size or bigger.
Since the digest (which is the key itself) is considered confidential and is
stored only in memory for only a limited amount of time, SHA-256 is considered
sufficiently strong for that purpose.
Size + plain-text + padding digest:
Since the digest is created of both the plain-text and the plain-text size,
as well as being encrypted, SHA-256 is considered sufficiently strong.
SHA-512 may increase security at the price of adding additional 32 bytes
to the encrypted password digest.
Stronger hash-functions like SHA-3 or BLAKE2b can be considered as a
replacement in the future.
#### Master password digest
In order to be able to decide whether the user typed a "wrong" master password,
before attempting to decrypt, Sylpheed stores a digest of the master password
in 'master_password_hash' in sylpheedrc.
100000 iterations of PBKDF2_HMAC with SHA-512 and 16 bytes salt is used.
Note that this digest is useless as a key and even if a plain-text that
produces the same digest is found, it will most probably be useless as a
master-password.
### Encryption & decryption scheme
#### Encryption
Input:
- plain-text password to be encrypted (P)
- plain-text master-password used for key derivation (M)
- integer minimum password length (0 < L < 100)
Output:
- an encrypted password digest (base64) (B)
Operation:
- generate 16 bytes of random data to be used as a salt (S)
- derive the key (K): K = SHA_256(S + M)
- produce a 2 byte string (N) indicating the length of P
- generate random padding and set N:
- if the length of P < L, produce L - P bytes of random data (R), N = "%02d"
- if the length of P >= L, N = "-1"
- produce a hash digest (H): H = SHA_256(N + P + R (if the length of P < L))
- encrypt (E): E = AES_256_CFB_ENCRYPT(H + N + P + R (if the length of P < L), K, IV=S)
- B = mpes1:BASE64_ENCODE(S + E)
example:
mpes1:vo7lsIpD7i6byBA6+vlUoF4OVDfEe+aYRRk4FRtfJ2gMY8M43Kj6WfdfgbViIOl83bI4XEc96okhPW5Mla813aAR1gbPjDg0xmCyIbWOiUv/dg==
#### Decryption
Input:
- encrypted password digest (base64) (B)
- plain-text master-password used for key derivation (M)
Output:
- plain-text password (P)
Operation:
- remove the prefix (mpes1:) and base64-decode the rest of the digest: B = BASE64_DECODE(B)
- fetch the first 16 bytes for the salt: S = B[0 : 15]
- derive the key (K): K = SHA_256(S + M)
- decrypt the rest of B (D): D = AES_256_CFB_DECRYPT(B[16 :], K, IV=S)
- extract the first 16 bytes for the hash digest (H): H = D[0 : 15]
- in order to detect data-inconsistency, assert H == SHA_256(D[16 :])
- extract the next 2 bytes for the length of P (N): N = D[16 : 17]
- fetch the plain-text:
- if N == "-1" the password is the remaining bytes of D: P = D[18 :]
- if N != "-1", extract the next N-bytes from D: P = D[18 : (18 + N)]
### Limitations
- currently only the 'password' and 'smtp_password' keys in accountrc
are encrypted.
A mechanism that allows for any key and even folders to be encrypted
should be considered in the future.
- currently it is not possible to select alternative ciphers, hash-functions
and modes of operation (without editing the source code).
- currently it is not possible to change your master password without having to
(re)set your passwords manually.
|