sqlite3_func_crypt.go raw

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