You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
4.0 KiB

  1. // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>.
  2. //
  3. // Use of this source code is governed by an MIT-style
  4. // license that can be found in the LICENSE file.
  5. package sqlite3
  6. import (
  7. "crypto/sha1"
  8. "crypto/sha256"
  9. "crypto/sha512"
  10. )
  11. // This file provides several different implementations for the
  12. // default embedded sqlite_crypt function.
  13. // This function is uses a ceasar-cypher by default
  14. // and is used within the UserAuthentication module to encode
  15. // the password.
  16. //
  17. // The provided functions can be used as an overload to the sqlite_crypt
  18. // function through the use of the RegisterFunc on the connection.
  19. //
  20. // Because the functions can serv a purpose to an end-user
  21. // without using the UserAuthentication module
  22. // the functions are default compiled in.
  23. //
  24. // From SQLITE3 - user-auth.txt
  25. // The sqlite_user.pw field is encoded by a built-in SQL function
  26. // "sqlite_crypt(X,Y)". The two arguments are both BLOBs. The first argument
  27. // is the plaintext password supplied to the sqlite3_user_authenticate()
  28. // interface. The second argument is the sqlite_user.pw value and is supplied
  29. // so that the function can extract the "salt" used by the password encoder.
  30. // The result of sqlite_crypt(X,Y) is another blob which is the value that
  31. // ends up being stored in sqlite_user.pw. To verify credentials X supplied
  32. // by the sqlite3_user_authenticate() routine, SQLite runs:
  33. //
  34. // sqlite_user.pw == sqlite_crypt(X, sqlite_user.pw)
  35. //
  36. // To compute an appropriate sqlite_user.pw value from a new or modified
  37. // password X, sqlite_crypt(X,NULL) is run. A new random salt is selected
  38. // when the second argument is NULL.
  39. //
  40. // The built-in version of of sqlite_crypt() uses a simple Ceasar-cypher
  41. // which prevents passwords from being revealed by searching the raw database
  42. // for ASCII text, but is otherwise trivally broken. For better password
  43. // security, the database should be encrypted using the SQLite Encryption
  44. // Extension or similar technology. Or, the application can use the
  45. // sqlite3_create_function() interface to provide an alternative
  46. // implementation of sqlite_crypt() that computes a stronger password hash,
  47. // perhaps using a cryptographic hash function like SHA1.
  48. // CryptEncoderSHA1 encodes a password with SHA1
  49. func CryptEncoderSHA1(pass []byte, hash interface{}) []byte {
  50. h := sha1.Sum(pass)
  51. return h[:]
  52. }
  53. // CryptEncoderSSHA1 encodes a password with SHA1 with the
  54. // configured salt.
  55. func CryptEncoderSSHA1(salt string) func(pass []byte, hash interface{}) []byte {
  56. return func(pass []byte, hash interface{}) []byte {
  57. s := []byte(salt)
  58. p := append(pass, s...)
  59. h := sha1.Sum(p)
  60. return h[:]
  61. }
  62. }
  63. // CryptEncoderSHA256 encodes a password with SHA256
  64. func CryptEncoderSHA256(pass []byte, hash interface{}) []byte {
  65. h := sha256.Sum256(pass)
  66. return h[:]
  67. }
  68. // CryptEncoderSSHA256 encodes a password with SHA256
  69. // with the configured salt
  70. func CryptEncoderSSHA256(salt string) func(pass []byte, hash interface{}) []byte {
  71. return func(pass []byte, hash interface{}) []byte {
  72. s := []byte(salt)
  73. p := append(pass, s...)
  74. h := sha256.Sum256(p)
  75. return h[:]
  76. }
  77. }
  78. // CryptEncoderSHA384 encodes a password with SHA384
  79. func CryptEncoderSHA384(pass []byte, hash interface{}) []byte {
  80. h := sha512.Sum384(pass)
  81. return h[:]
  82. }
  83. // CryptEncoderSSHA384 encodes a password with SHA384
  84. // with the configured salt
  85. func CryptEncoderSSHA384(salt string) func(pass []byte, hash interface{}) []byte {
  86. return func(pass []byte, hash interface{}) []byte {
  87. s := []byte(salt)
  88. p := append(pass, s...)
  89. h := sha512.Sum384(p)
  90. return h[:]
  91. }
  92. }
  93. // CryptEncoderSHA512 encodes a password with SHA512
  94. func CryptEncoderSHA512(pass []byte, hash interface{}) []byte {
  95. h := sha512.Sum512(pass)
  96. return h[:]
  97. }
  98. // CryptEncoderSSHA512 encodes a password with SHA512
  99. // with the configured salt
  100. func CryptEncoderSSHA512(salt string) func(pass []byte, hash interface{}) []byte {
  101. return func(pass []byte, hash interface{}) []byte {
  102. s := []byte(salt)
  103. p := append(pass, s...)
  104. h := sha512.Sum512(p)
  105. return h[:]
  106. }
  107. }
  108. // EOF