diff options
| author | Simeon Simeonov | 2018-04-11 11:04:02 +0200 |
|---|---|---|
| committer | Simeon Simeonov | 2018-04-11 11:04:02 +0200 |
| commit | 6c86fc92d3f4f28ce245e47027a7a44ac1be3f55 (patch) | |
| tree | bd8caf857209ea5db7d146c53f400a13ff1cb9a3 | |
| parent | 62c87a837463fdf09d9e7d1a605000c21f8da060 (diff) | |
Update README
| -rw-r--r-- | README | 218 |
1 files changed, 218 insertions, 0 deletions
| @@ -288,3 +288,221 @@ at the target directory. | |||
| 288 | 288 | ||
| 289 | -- | 289 | -- |
| 290 | Hiroyuki Yamamoto <hiro-y@kcn.ne.jp> | 290 | Hiroyuki Yamamoto <hiro-y@kcn.ne.jp> |
| 291 | |||
| 292 | |||
| 293 | Master password (by sgs) | ||
| 294 | ======================== | ||
| 295 | |||
| 296 | The master password feature is developed by | ||
| 297 | Simeon Simeonov (sgs - sgs@pichove.org) and is currently in an experimental | ||
| 298 | state. | ||
| 299 | |||
| 300 | |||
| 301 | Motivation | ||
| 302 | ---------- | ||
| 303 | |||
| 304 | Currently Sylpheed is storing passwords in palin-text. One can always refrain | ||
| 305 | from storing passwords and let Sylpheed prompt for them, but the more accounts | ||
| 306 | one has, the more annoying this becomes. | ||
| 307 | |||
| 308 | The goal is to have the passwords stored in a secure way and let Sylpheed only | ||
| 309 | prompt for the master password. | ||
| 310 | |||
| 311 | |||
| 312 | Security goals | ||
| 313 | -------------- | ||
| 314 | |||
| 315 | - attacker (A) should not be able to derive the password from the digest | ||
| 316 | |||
| 317 | - A should not be able to derive the master password even if she has | ||
| 318 | read and write access to the storage | ||
| 319 | |||
| 320 | - A should not be able to determine the length of the encrypted password | ||
| 321 | even if she has read and write access to the storage | ||
| 322 | |||
| 323 | - A should not be able to craft an edited password without obtaining the | ||
| 324 | master password | ||
| 325 | |||
| 326 | - a warning / prompt should be given if a user accidently types in a "wrong" | ||
| 327 | master password before decryption is initiated | ||
| 328 | |||
| 329 | |||
| 330 | Usage in Sylpheed | ||
| 331 | ----------------- | ||
| 332 | |||
| 333 | - backup your Sylpheed profile (often $HOME/.sylpheed-2.0)! | ||
| 334 | |||
| 335 | - start Sylpheed and open Configuration -> Common preferences...! | ||
| 336 | |||
| 337 | - select the "Master password" tab, enable "Use master password" and | ||
| 338 | apply the changes! | ||
| 339 | |||
| 340 | - restart Sylpheed (exit and then start Sylpheed again)! | ||
| 341 | |||
| 342 | - you will be asked to type and verify a new master password. | ||
| 343 | |||
| 344 | Note: | ||
| 345 | Sylpheed will automatically convert existing stored passwords, but it will not | ||
| 346 | touch your backups. You will have to remove all remnants of plain-text | ||
| 347 | passwords manually. | ||
| 348 | |||
| 349 | |||
| 350 | Choice of cryptographic primitives | ||
| 351 | ---------------------------------- | ||
| 352 | |||
| 353 | The primary concern when selecting cryptographic primitives was portability. | ||
| 354 | The desire was to go for primitives that are both strong and available in all | ||
| 355 | supported production distributions of OpenSSL and LibreSSL. | ||
| 356 | |||
| 357 | |||
| 358 | Cipher | ||
| 359 | ...... | ||
| 360 | |||
| 361 | When it comes to implementation, there are several advantages in using stream | ||
| 362 | cipher or a block cipher that behaves like a stream cipher when used in a | ||
| 363 | certain mode of operation. One is avoiding to deal with padding. | ||
| 364 | |||
| 365 | AES-256 operating in CFB was selected for these reasons. | ||
| 366 | ChaCha20 should be considered as a replacement in the future. | ||
| 367 | |||
| 368 | |||
| 369 | Hash-function | ||
| 370 | ............. | ||
| 371 | |||
| 372 | Hash-functions are used for: | ||
| 373 | - key derivation | ||
| 374 | - plain-text digest | ||
| 375 | |||
| 376 | Those operations do not have to use the same hash-function. | ||
| 377 | (See the "Encryption & decryption scheme" section for more details!) | ||
| 378 | |||
| 379 | Key-derivation: | ||
| 380 | Since AES-256 uses a 256 bits key, we need a hash-function with at least | ||
| 381 | the same digest size or bigger. | ||
| 382 | Since the digest (which is the key itself) is considered confidential and is | ||
| 383 | stored only in memory for only a limited amount of time, SHA-256 is considered | ||
| 384 | sufficiently strong for that purpose. | ||
| 385 | |||
| 386 | Size + plain-text + padding digest: | ||
| 387 | Since the digest is created of both the plain-text and the plain-text size, | ||
| 388 | as well as being encrypted, SHA-256 is considered sufficiently strong. | ||
| 389 | SHA-512 may increase security at the price of adding additional 32 bytes | ||
| 390 | to the encrypted password digest. | ||
| 391 | |||
| 392 | Stronger hash-functions like SHA-3 or BLAKE2b can be considered as a | ||
| 393 | replacement in the future. | ||
| 394 | |||
| 395 | |||
| 396 | Master password digest | ||
| 397 | ...................... | ||
| 398 | |||
| 399 | In order to be able to decide whether the user typed a "wrong" master password, | ||
| 400 | before attempting to decrypt, Sylpheed stores a digest of the master password | ||
| 401 | in 'master_password_hash' in sylpheedrc. | ||
| 402 | 100000 iterations of PBKDF2_HMAC with SHA-512 and 16 bytes salt is used. | ||
| 403 | Note that this digest is useless as a key and even if a plain-text that | ||
| 404 | produces the same digest is found, it will most probably be useless as a | ||
| 405 | master-password. | ||
| 406 | |||
| 407 | |||
| 408 | Encryption & decryption scheme | ||
| 409 | ------------------------------ | ||
| 410 | |||
| 411 | |||
| 412 | Encryption | ||
| 413 | .......... | ||
| 414 | |||
| 415 | |||
| 416 | Input: | ||
| 417 | |||
| 418 | - palin-text password to be encrypted (P) | ||
| 419 | |||
| 420 | - plain-text master-password used for key derivation (M) | ||
| 421 | |||
| 422 | - integer minimum password length (0 < L < 100) | ||
| 423 | |||
| 424 | |||
| 425 | Output: | ||
| 426 | |||
| 427 | - an encrypted password digest (base64) (B) | ||
| 428 | |||
| 429 | |||
| 430 | Operation: | ||
| 431 | |||
| 432 | - generate 16 bytes of random data to be used as a salt (S) | ||
| 433 | |||
| 434 | - derive the key (K): K = SHA_256(S + M) | ||
| 435 | |||
| 436 | - produce a 2 byte string (N) indicating the length of P | ||
| 437 | |||
| 438 | - if the length of P < L, produce L - P bytes of random data (R), N = "%02d" | ||
| 439 | if the length of P >= L, N = "-1" | ||
| 440 | |||
| 441 | - produce a hash digest (H): H = SHA_256(N + P + R (if the length of P < L)) | ||
| 442 | |||
| 443 | - encrypt (E): E = AES_256_CFB_ENCRYPT(H + N + P + R (if the length of P < L), K) | ||
| 444 | |||
| 445 | - B = mpes1:BASE64_ENCODE(S + E) | ||
| 446 | example: | ||
| 447 | mpes1:vo7lsIpD7i6byBA6+vlUoF4OVDfEe+aYRRk4FRtfJ2gMY8M43Kj6WfdfgbViIOl83bI4XEc96okhPW5Mla813aAR1gbPjDg0xmCyIbWOiUv/dg== | ||
| 448 | |||
| 449 | |||
| 450 | Decryption | ||
| 451 | .......... | ||
| 452 | |||
| 453 | |||
| 454 | Input: | ||
| 455 | |||
| 456 | - encrypted password digest (base64) (B) | ||
| 457 | |||
| 458 | - plain-text master-password used for key derivation (M) | ||
| 459 | |||
| 460 | |||
| 461 | Output: | ||
| 462 | |||
| 463 | - palin-text password (P) | ||
| 464 | |||
| 465 | |||
| 466 | Operation: | ||
| 467 | |||
| 468 | - remove the prefix (mpes1:) and base64-decode the rest of the digest: B = BASE64_DECODE(B) | ||
| 469 | |||
| 470 | - fetch the first 16 bytes for the salt: S = B[0 : 15] | ||
| 471 | |||
| 472 | - derive the key (K): K = SHA_256(S + M) | ||
| 473 | |||
| 474 | - decrypt the rest of B (D): D = AES_256_CFB_DECRYPT(B[16 :], K) | ||
| 475 | |||
| 476 | - extract the first 16 bytes for the hash digest (H): H = D[0 : 15] | ||
| 477 | |||
| 478 | - in order to detect data-inconsistency, assert H == SHA_256(D[16 :]) | ||
| 479 | |||
| 480 | - extract the next 2 bytes for the length of P (N): N = D[16 : 17] | ||
| 481 | |||
| 482 | - if N == "-1" the password is the remaining bytes of D: P = D[18 :] | ||
| 483 | if N != "-1", extract the next N-bytes from D: P = D[18 : (18 + N)] | ||
| 484 | |||
| 485 | |||
| 486 | Limitations | ||
| 487 | ----------- | ||
| 488 | |||
| 489 | - when Sylpheed starts, the master-password is loaded into memory and remains | ||
| 490 | there as long as Sylpheed is running. Currently no strong mechanisms, | ||
| 491 | preventing someone with access to the memory from snatching it, | ||
| 492 | are implemented. | ||
| 493 | "Unloading" the master-password immediately after | ||
| 494 | account-processing (decryption) should be considered in the future. | ||
| 495 | |||
| 496 | - currently only the 'password' and 'smtp_password' keys in accountrc | ||
| 497 | are encrypted. | ||
| 498 | A machanism that allows for any key and even folders to be encrypted | ||
| 499 | should be considered in the future. | ||
| 500 | |||
| 501 | - currently it is not possible to select alternative ciphers, hash-functions | ||
| 502 | and modes of operation (without editing the source code). | ||
| 503 | |||
| 504 | - currently it is not possible to change your master password without having to | ||
| 505 | set your passwords manually. | ||
| 506 | |||
| 507 | -- | ||
| 508 | Simeon Simeonov <sgs [ATTT] pichove (DOT) org> | ||
