github.com/aldelo/common@v1.5.1/crypto/crypto.go (about)

     1  package crypto
     2  
     3  /*
     4   * Copyright 2020-2023 Aldelo, LP
     5   *
     6   * Licensed under the Apache License, Version 2.0 (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at
     9   *
    10   *     http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing, software
    13   * distributed under the License is distributed on an "AS IS" BASIS,
    14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15   * See the License for the specific language governing permissions and
    16   * limitations under the License.
    17   */
    18  
    19  import (
    20  	"crypto"
    21  	"crypto/aes"
    22  	"crypto/cipher"
    23  	"crypto/hmac"
    24  	"crypto/md5"
    25  	"crypto/rand"
    26  	"crypto/rsa"
    27  	"crypto/sha256"
    28  	"crypto/x509"
    29  	"encoding/pem"
    30  	"errors"
    31  	"fmt"
    32  	"hash/fnv"
    33  	"io"
    34  	"strings"
    35  
    36  	"golang.org/x/crypto/bcrypt"
    37  	"golang.org/x/crypto/scrypt"
    38  
    39  	util "github.com/aldelo/common"
    40  	"github.com/aldelo/common/ascii"
    41  )
    42  
    43  // ================================================================================================================
    44  // KEY HELPERS
    45  // ================================================================================================================
    46  
    47  // Generate32ByteRandomKey will generate a random 32 byte key based on passphrase and random salt,
    48  // passphrase does not need to be any specific length
    49  func Generate32ByteRandomKey(passphrase string) (string, error) {
    50  	// validate passphrase
    51  	if len(passphrase) == 0 {
    52  		return "", errors.New("Passphrase is Required")
    53  	}
    54  
    55  	// generate salt
    56  	salt := make([]byte, 32)
    57  
    58  	// populate salt
    59  	if _, err1 := io.ReadFull(rand.Reader, salt); err1 != nil {
    60  		return "", err1
    61  	}
    62  
    63  	// generate key
    64  	key, err2 := scrypt.Key([]byte(passphrase), salt, 32768, 8, 1, 32)
    65  
    66  	if err2 != nil {
    67  		return "", err2
    68  	}
    69  
    70  	return util.ByteToHex(key), nil
    71  }
    72  
    73  // ================================================================================================================
    74  // FNV HELPERS
    75  // ================================================================================================================
    76  
    77  // FnvHashDigit returns persistent hash digit value, limited by the digit limit parameter
    78  func FnvHashDigit(data string, digitLimit int) int {
    79  	h := fnv.New32a()
    80  	_, _ = h.Write([]byte(data))
    81  
    82  	if digitLimit < 2 {
    83  		digitLimit = 2
    84  	}
    85  
    86  	return int(h.Sum32()%uint32(digitLimit-1) + 1)
    87  }
    88  
    89  // ================================================================================================================
    90  // MD5 HELPERS
    91  // ================================================================================================================
    92  
    93  // Md5 hashing
    94  func Md5(data string, salt string) string {
    95  	b := []byte(data + salt)
    96  	return fmt.Sprintf("%X", md5.Sum(b))
    97  }
    98  
    99  // ================================================================================================================
   100  // SHA256 HELPERS
   101  // ================================================================================================================
   102  
   103  // Sha256 hashing (always 64 bytes output)
   104  func Sha256(data string, salt string) string {
   105  	b := []byte(data + salt)
   106  	return fmt.Sprintf("%X", sha256.Sum256(b))
   107  }
   108  
   109  // ================================================================================================================
   110  // BCRYPT HELPERS
   111  // ================================================================================================================
   112  
   113  // PasswordHash uses BCrypt to hash the given password and return a corresponding hash,
   114  // suggested cost = 13 (440ms),
   115  // if cost is left as 0, then default 13 is assumed
   116  func PasswordHash(password string, cost int) (string, error) {
   117  	if cost <= 0 {
   118  		cost = 13
   119  	} else if cost < 12 {
   120  		cost = 12
   121  	} else if cost > 31 {
   122  		cost = 31
   123  	}
   124  
   125  	b, err := bcrypt.GenerateFromPassword([]byte(password), cost)
   126  
   127  	if err != nil {
   128  		return "", err
   129  	}
   130  
   131  	return string(b), nil
   132  }
   133  
   134  // PasswordVerify uses BCrypt to verify the input password against a prior hash version to see if match
   135  func PasswordVerify(password string, hash string) (bool, error) {
   136  	err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
   137  
   138  	if err != nil {
   139  		return false, err
   140  	}
   141  
   142  	return true, nil
   143  }
   144  
   145  // ================================================================================================================
   146  // AES-GCM HELPERS
   147  // ================================================================================================================
   148  
   149  // AesGcmEncrypt will encrypt using aes gcm 256 bit,
   150  // passphrase must be 32 bytes, if over 32 bytes, it be truncated,
   151  // encrypted data is represented in hex value
   152  func AesGcmEncrypt(data string, passphrase string) (string, error) {
   153  	// ensure data has value
   154  	if len(data) == 0 {
   155  		return "", errors.New("Data to Encrypt is Required")
   156  	}
   157  
   158  	// ensure passphrase is 32 bytes
   159  	// note: passphrase is just ascii, not hex, client should not convert to hex
   160  	if len(passphrase) < 32 {
   161  		return "", errors.New("Passphrase Must Be 32 Bytes")
   162  	}
   163  
   164  	// cut the passphrase to 32 bytes only
   165  	passphrase = util.Left(passphrase, 32)
   166  
   167  	// convert data and passphrase into byte array
   168  	text := []byte(data)
   169  	key := []byte(passphrase)
   170  
   171  	// generate a new aes cipher using the 32 bytes key
   172  	c, err1 := aes.NewCipher(key)
   173  
   174  	// on error stop
   175  	if err1 != nil {
   176  		return "", err1
   177  	}
   178  
   179  	// using gcm (Galois/Counter Mode) for symmetric key cryptographic block ciphers
   180  	// https://en.wikipedia.org/wiki/Galois/Counter_Mode
   181  	gcm, err2 := cipher.NewGCM(c)
   182  
   183  	// on error stop
   184  	if err2 != nil {
   185  		return "", err2
   186  	}
   187  
   188  	// create a new byte array the size of the nonce,
   189  	// which must be passed to Seal
   190  	nonce := make([]byte, gcm.NonceSize())
   191  
   192  	// populate our nonce with a cryptographically secure random sequence
   193  	if _, err3 := io.ReadFull(rand.Reader, nonce); err3 != nil {
   194  		return "", err3
   195  	}
   196  
   197  	// encrypt our text using Seal function,
   198  	// Seal encrypts and authenticates plaintext,
   199  	// authenticates the additional data and appends the result to dst,
   200  	// returning the updated slice,
   201  	// the nonce must be NonceSize() bytes long and unique for all time, for a given key
   202  
   203  	// return util.ByteToHex(gcm.Seal(nonce, nonce, text, nil)), nil
   204  	return util.ByteToHex(gcm.Seal(nonce, nonce, text, nil)), nil
   205  }
   206  
   207  // AesGcmDecrypt will decrypt using aes gcm 256 bit,
   208  // passphrase must be 32 bytes, if over 32 bytes, it be truncated
   209  func AesGcmDecrypt(data string, passphrase string) (string, error) {
   210  	// ensure data has value
   211  	if len(data) == 0 {
   212  		return "", errors.New("Data to Decrypt is Required")
   213  	}
   214  
   215  	// ensure passphrase is 32 bytes
   216  	// note: passphrase is just ascii, not hex, client should not convert to hex
   217  	if len(passphrase) < 32 {
   218  		return "", errors.New("Passphrase Must Be 32 Bytes")
   219  	}
   220  
   221  	// cut the passphrase to 32 bytes only
   222  	passphrase = util.Left(passphrase, 32)
   223  
   224  	// convert data and passphrase into byte array
   225  	text, err := util.HexToByte(data)
   226  
   227  	if err != nil {
   228  		return "", err
   229  	}
   230  
   231  	key := []byte(passphrase)
   232  
   233  	// create aes cipher
   234  	c, err1 := aes.NewCipher(key)
   235  
   236  	// on error stop
   237  	if err1 != nil {
   238  		return "", err1
   239  	}
   240  
   241  	// create gcm (Galois/Counter Mode) to decrypt
   242  	gcm, err2 := cipher.NewGCM(c)
   243  
   244  	// on error stop
   245  	if err2 != nil {
   246  		return "", err2
   247  	}
   248  
   249  	// create nonce
   250  	nonceSize := gcm.NonceSize()
   251  
   252  	if len(text) < nonceSize {
   253  		return "", errors.New("Cipher Text Smaller Than Nonce Size")
   254  	}
   255  
   256  	// get cipher text
   257  	nonce, text := text[:nonceSize], text[nonceSize:]
   258  
   259  	// decrypt cipher text
   260  	plaintext, err3 := gcm.Open(nil, nonce, text, nil)
   261  
   262  	// on error stop
   263  	if err3 != nil {
   264  		return "", err3
   265  	}
   266  
   267  	// return decrypted text
   268  	return string(plaintext), nil
   269  }
   270  
   271  // ================================================================================================================
   272  // AES-CFB HELPERS
   273  // ================================================================================================================
   274  
   275  // AesCfbEncrypt will encrypt using aes cfb 256 bit,
   276  // passphrase must be 32 bytes, if over 32 bytes, it be truncated,
   277  // encrypted data is represented in hex value
   278  func AesCfbEncrypt(data string, passphrase string) (string, error) {
   279  	// ensure data has value
   280  	if len(data) == 0 {
   281  		return "", errors.New("Data to Encrypt is Required")
   282  	}
   283  
   284  	// ensure passphrase is 32 bytes
   285  	if len(passphrase) < 32 {
   286  		return "", errors.New("Passphrase Must Be 32 Bytes")
   287  	}
   288  
   289  	// cut the passphrase to 32 bytes only
   290  	passphrase = util.Left(passphrase, 32)
   291  
   292  	// convert data and passphrase into byte array
   293  	text := []byte(data)
   294  	key := []byte(passphrase)
   295  
   296  	// generate a new aes cipher using the 32 bytes key
   297  	c, err1 := aes.NewCipher(key)
   298  
   299  	// on error stop
   300  	if err1 != nil {
   301  		return "", err1
   302  	}
   303  
   304  	// iv needs to be unique, but doesn't have to be secure,
   305  	// its common to put it at the beginning of the cipher text
   306  	cipherText := make([]byte, aes.BlockSize+len(text))
   307  
   308  	iv := cipherText[:aes.BlockSize]
   309  
   310  	if _, err2 := io.ReadFull(rand.Reader, iv); err2 != nil {
   311  		return "", err2
   312  	}
   313  
   314  	// encrypt
   315  	stream := cipher.NewCFBEncrypter(c, iv)
   316  	stream.XORKeyStream(cipherText[aes.BlockSize:], text)
   317  
   318  	// return encrypted data
   319  	return util.ByteToHex(cipherText), nil
   320  }
   321  
   322  // AesCfbDecrypt will decrypt using aes cfb 256 bit,
   323  // passphrase must be 32 bytes, if over 32 bytes, it be truncated
   324  func AesCfbDecrypt(data string, passphrase string) (string, error) {
   325  	// ensure data has value
   326  	if len(data) == 0 {
   327  		return "", errors.New("Data to Decrypt is Required")
   328  	}
   329  
   330  	// ensure passphrase is 32 bytes
   331  	if len(passphrase) < 32 {
   332  		return "", errors.New("Passphrase Must Be 32 Bytes")
   333  	}
   334  
   335  	// cut the passphrase to 32 bytes only
   336  	passphrase = util.Left(passphrase, 32)
   337  
   338  	// convert data and passphrase into byte array
   339  	text, err := util.HexToByte(data)
   340  
   341  	if err != nil {
   342  		return "", err
   343  	}
   344  
   345  	key := []byte(passphrase)
   346  
   347  	// create aes cipher
   348  	c, err1 := aes.NewCipher(key)
   349  
   350  	// on error stop
   351  	if err1 != nil {
   352  		return "", err1
   353  	}
   354  
   355  	// ensure cipher block size appropriate
   356  	if len(text) < aes.BlockSize {
   357  		return "", errors.New("Cipher Text Block Size Too Short")
   358  	}
   359  
   360  	// iv needs to be unique, doesn't have to secured,
   361  	// it's common to put iv at the beginning of the cipher text
   362  	iv := text[:aes.BlockSize]
   363  	text = text[aes.BlockSize:]
   364  
   365  	// decrypt
   366  	stream := cipher.NewCFBDecrypter(c, iv)
   367  
   368  	// XORKeyStream can work in-place if two arguments are the same
   369  	stream.XORKeyStream(text, text)
   370  
   371  	// return decrypted data
   372  	return string(text), nil
   373  }
   374  
   375  // ================================================================================================================
   376  // AES-CBC HELPERS
   377  // ================================================================================================================
   378  
   379  // AesCbcEncrypt will encrypt using aes cbc 256 bit,
   380  // passphrase must be 32 bytes, if over 32 bytes, it be truncated,
   381  // encrypted data is represented in hex value
   382  func AesCbcEncrypt(data string, passphrase string) (string, error) {
   383  	// ensure data has value
   384  	if len(data) == 0 {
   385  		return "", errors.New("Data to Encrypt is Required")
   386  	}
   387  
   388  	// ensure passphrase is 32 bytes
   389  	if len(passphrase) < 32 {
   390  		return "", errors.New("Passphrase Must Be 32 Bytes")
   391  	}
   392  
   393  	// cut the passphrase to 32 bytes only
   394  	passphrase = util.Left(passphrase, 32)
   395  
   396  	// in cbc, data must be in block size of aes (multiples of 16 bytes),
   397  	// otherwise padding needs to be performed
   398  	if len(data)%aes.BlockSize != 0 {
   399  		// pad with blank spaces up to 16 bytes
   400  		data = util.Padding(data, util.NextFixedLength(data, aes.BlockSize), true, ascii.AsciiToString(ascii.NUL))
   401  	}
   402  
   403  	// convert data and passphrase into byte array
   404  	text := []byte(data)
   405  	key := []byte(passphrase)
   406  
   407  	// generate a new aes cipher using the 32 bytes key
   408  	c, err1 := aes.NewCipher(key)
   409  
   410  	// on error stop
   411  	if err1 != nil {
   412  		return "", err1
   413  	}
   414  
   415  	// iv needs to be unique, but doesn't have to be secure,
   416  	// its common to put it at the beginning of the cipher text
   417  	cipherText := make([]byte, aes.BlockSize+len(text))
   418  
   419  	// create iv, length must be equal to block size
   420  	iv := cipherText[:aes.BlockSize]
   421  
   422  	if _, err2 := io.ReadFull(rand.Reader, iv); err2 != nil {
   423  		return "", err2
   424  	}
   425  
   426  	// encrypt
   427  	mode := cipher.NewCBCEncrypter(c, iv)
   428  	mode.CryptBlocks(cipherText[aes.BlockSize:], text)
   429  
   430  	// return encrypted data
   431  	return util.ByteToHex(cipherText), nil
   432  }
   433  
   434  // AesCbcDecrypt will decrypt using aes cbc 256 bit,
   435  // passphrase must be 32 bytes, if over 32 bytes, it be truncated
   436  func AesCbcDecrypt(data string, passphrase string) (string, error) {
   437  	// ensure data has value
   438  	if len(data) == 0 {
   439  		return "", errors.New("Data to Decrypt is Required")
   440  	}
   441  
   442  	// ensure passphrase is 32 bytes
   443  	if len(passphrase) < 32 {
   444  		return "", errors.New("Passphrase Must Be 32 Bytes")
   445  	}
   446  
   447  	// cut the passphrase to 32 bytes only
   448  	passphrase = util.Left(passphrase, 32)
   449  
   450  	// convert data and passphrase into byte array
   451  	text, err := util.HexToByte(data)
   452  
   453  	if err != nil {
   454  		return "", err
   455  	}
   456  
   457  	key := []byte(passphrase)
   458  
   459  	// create aes cipher
   460  	c, err1 := aes.NewCipher(key)
   461  
   462  	// on error stop
   463  	if err1 != nil {
   464  		return "", err1
   465  	}
   466  
   467  	// ensure cipher block size appropriate
   468  	if len(text) < aes.BlockSize {
   469  		return "", errors.New("Cipher Text Block Size Too Short")
   470  	}
   471  
   472  	// iv needs to be unique, doesn't have to secured,
   473  	// it's common to put iv at the beginning of the cipher text
   474  	iv := text[:aes.BlockSize]
   475  	text = text[aes.BlockSize:]
   476  
   477  	// cbc mode always work in whole blocks
   478  	if len(text)%aes.BlockSize != 0 {
   479  		return "", errors.New("Cipher Text Must Be In Multiple of Block Size")
   480  	}
   481  
   482  	// decrypt
   483  	mode := cipher.NewCBCDecrypter(c, iv)
   484  	mode.CryptBlocks(text, text)
   485  
   486  	// return decrypted data
   487  	return strings.ReplaceAll(string(text[:]), ascii.AsciiToString(ascii.NUL), ""), nil
   488  }
   489  
   490  // ================================================================================================================
   491  // HMAC HELPERS
   492  // ================================================================================================================
   493  
   494  // AppendHmac will calculate the hmac for the given encrypted data based on the given key,
   495  // and append the Hmac to the end of the encrypted data and return the newly assembled encrypted data with hmac
   496  // key must be 32 bytes
   497  func AppendHmac(encryptedData string, key string) (string, error) {
   498  	// ensure data has value
   499  	if len(encryptedData) == 0 {
   500  		return "", errors.New("Data is Required")
   501  	}
   502  
   503  	// ensure key is 32 bytes
   504  	if len(key) < 32 {
   505  		return "", errors.New("Key Must Be 32 Bytes")
   506  	}
   507  
   508  	data := []byte(encryptedData)
   509  
   510  	// cut the key to 32 bytes only
   511  	key = util.Left(key, 32)
   512  
   513  	// new hmac
   514  	macProducer := hmac.New(sha256.New, []byte(key))
   515  	macProducer.Write(data)
   516  
   517  	// generate mac
   518  	strMac := util.ByteToHex(macProducer.Sum(nil))
   519  	mac := []byte(strMac)
   520  
   521  	// append and return
   522  	return string(append(data, mac...)), nil
   523  }
   524  
   525  // ValidateHmac will verify if the appended hmac validates against the message based on the given key,
   526  // and parse the hmac out and return the actual message if hmac validation succeeds,
   527  // if hmac validation fails, then blank is returned and the error contains the failure reason
   528  func ValidateHmac(encryptedDataWithHmac string, key string) (string, error) {
   529  	// ensure data has value
   530  	if len(encryptedDataWithHmac) <= 64 { // hex is 2x the byte, so 32 normally is now 64
   531  		return "", errors.New("Data with HMAC is Required")
   532  	}
   533  
   534  	// ensure key is 32 bytes
   535  	if len(key) < 32 {
   536  		return "", errors.New("Key Must Be 32 Bytes")
   537  	}
   538  
   539  	// cut the key to 32 bytes only
   540  	key = util.Left(key, 32)
   541  
   542  	// data to byte
   543  	data := []byte(encryptedDataWithHmac)
   544  
   545  	// parse message
   546  	message := data[:len(data)-64]
   547  	mac, err := util.HexToByte(string(data[len(data)-64:]))
   548  
   549  	if err != nil {
   550  		return "", err
   551  	}
   552  
   553  	// new mac
   554  	macProducer := hmac.New(sha256.New, []byte(key))
   555  	macProducer.Write(message)
   556  
   557  	// get calculated mac
   558  	calculatedMac := macProducer.Sum(nil)
   559  
   560  	if hmac.Equal(mac, calculatedMac) {
   561  		// hmac match, return encrypted data without hmac
   562  		return string(message), nil
   563  	}
   564  
   565  	// if process gets here, then hmac failed
   566  	return "", errors.New("HMAC Verification Failed")
   567  }
   568  
   569  // ================================================================================================================
   570  // RSA HELPERS
   571  // ================================================================================================================
   572  
   573  // RsaCreateKey generates the private and public key pair,
   574  // expressed in hex code value
   575  func RsaCreateKey() (privateKey string, publicKey string, err error) {
   576  	// generate new private key
   577  	rsaKey, err := rsa.GenerateKey(rand.Reader, 2048)
   578  
   579  	if err != nil {
   580  		return "", "", err
   581  	}
   582  
   583  	// get the public key
   584  	rsaPublicKey := &rsaKey.PublicKey
   585  
   586  	// get private key in bytes
   587  	bytesPrivateKey := pem.EncodeToMemory(&pem.Block{
   588  		Type:  "RSA PRIVATE KEY",
   589  		Bytes: x509.MarshalPKCS1PrivateKey(rsaKey)})
   590  
   591  	// get public key in bytes
   592  	bytesPublicKey := pem.EncodeToMemory(&pem.Block{
   593  		Type:  "RSA PUBLIC KEY",
   594  		Bytes: x509.MarshalPKCS1PublicKey(rsaPublicKey)})
   595  
   596  	// return result
   597  	return util.ByteToHex(bytesPrivateKey), util.ByteToHex(bytesPublicKey), nil
   598  }
   599  
   600  // rsaPrivateKeyFromHex converts hex string private key into rsa private key object
   601  func rsaPrivateKeyFromHex(privateKeyHex string) (*rsa.PrivateKey, error) {
   602  	// convert hex to bytes
   603  	bytesPrivateKey, err := util.HexToByte(privateKeyHex)
   604  
   605  	if err != nil {
   606  		return nil, err
   607  	}
   608  
   609  	// convert byte to object
   610  	block, _ := pem.Decode(bytesPrivateKey)
   611  
   612  	if block == nil {
   613  		return nil, errors.New("RSA Private Key From Hex Fail: " + "Pem Block Nil")
   614  	}
   615  
   616  	enc := x509.IsEncryptedPEMBlock(block)
   617  	b := block.Bytes
   618  
   619  	if enc {
   620  		b, err = x509.DecryptPEMBlock(block, nil)
   621  
   622  		if err != nil {
   623  			return nil, err
   624  		}
   625  	}
   626  
   627  	// parse key
   628  	key, err1 := x509.ParsePKCS1PrivateKey(b)
   629  
   630  	if err1 != nil {
   631  		return nil, err1
   632  	}
   633  
   634  	// return private key
   635  	return key, nil
   636  }
   637  
   638  // rsaPrivateKeyFromPem converts pkcs1 string private key into rsa private key object
   639  func rsaPrivateKeyFromPem(privateKeyPem string) (*rsa.PrivateKey, error) {
   640  	block, _ := pem.Decode([]byte(privateKeyPem))
   641  
   642  	if block == nil {
   643  		return nil, errors.New("RSA Private Key From Pem Fail: " + "Pem Block Nil")
   644  	}
   645  
   646  	if key, err := x509.ParsePKCS1PrivateKey(block.Bytes); err != nil {
   647  		return nil, err
   648  	} else {
   649  		return key, nil
   650  	}
   651  }
   652  
   653  // rsaPublicKeyFromHex converts hex string public key into rsa public key object
   654  func rsaPublicKeyFromHex(publicKeyHex string) (*rsa.PublicKey, error) {
   655  	// convert hex to bytes
   656  	bytesPublicKey, err := util.HexToByte(publicKeyHex)
   657  
   658  	if err != nil {
   659  		return nil, err
   660  	}
   661  
   662  	// convert byte to object
   663  	block, _ := pem.Decode(bytesPublicKey)
   664  
   665  	if block == nil {
   666  		return nil, errors.New("RSA Public Key From Hex Fail: " + "Pem Block Nil")
   667  	}
   668  
   669  	enc := x509.IsEncryptedPEMBlock(block)
   670  	b := block.Bytes
   671  
   672  	if enc {
   673  		b, err = x509.DecryptPEMBlock(block, nil)
   674  
   675  		if err != nil {
   676  			return nil, err
   677  		}
   678  	}
   679  
   680  	// parse key
   681  	key, err1 := x509.ParsePKCS1PublicKey(b)
   682  
   683  	if err1 != nil {
   684  		return nil, err1
   685  	}
   686  
   687  	// return public key
   688  	return key, nil
   689  }
   690  
   691  // rsaPublicKeyFromPem converts certificate string public key into rsa public key object
   692  func rsaPublicKeyFromPem(publicKeyPem string) (*rsa.PublicKey, error) {
   693  	block, _ := pem.Decode([]byte(publicKeyPem))
   694  
   695  	if block == nil {
   696  		return nil, errors.New("RSA Public Key From Pem Fail: " + "Pem Block Nil")
   697  	}
   698  
   699  	if key, err := x509.ParsePKIXPublicKey(block.Bytes); err != nil {
   700  		return nil, err
   701  	} else {
   702  		return key.(*rsa.PublicKey), nil
   703  	}
   704  }
   705  
   706  // RsaPublicKeyEncrypt will encrypt given data using rsa public key,
   707  // encrypted data is represented in hex value
   708  //
   709  // publicKeyHexOrPem = can be either HEX or PEM
   710  func RsaPublicKeyEncrypt(data string, publicKeyHexOrPem string) (string, error) {
   711  	// data must not exceed 214 bytes
   712  	if len(data) > 214 {
   713  		return "", errors.New("RSA Public Key Encrypt Data Must Not Exceed 214 Bytes")
   714  	}
   715  
   716  	if len(data) == 0 {
   717  		return "", errors.New("Data To Encrypt is Required")
   718  	}
   719  
   720  	// get public key
   721  	var publicKey *rsa.PublicKey
   722  	var err error
   723  
   724  	if util.Left(publicKeyHexOrPem, 26) == "-----BEGIN PUBLIC KEY-----" && util.Right(publicKeyHexOrPem, 24) == "-----END PUBLIC KEY-----" {
   725  		// get public key from pem
   726  		publicKey, err = rsaPublicKeyFromPem(publicKeyHexOrPem)
   727  	} else {
   728  		// get public key from hex
   729  		publicKey, err = rsaPublicKeyFromHex(publicKeyHexOrPem)
   730  	}
   731  
   732  	if err != nil {
   733  		return "", err
   734  	}
   735  
   736  	// convert data into byte array
   737  	msg := []byte(data)
   738  
   739  	// create hash
   740  	hash := sha256.New()
   741  
   742  	// encrypt
   743  	cipherText, err1 := rsa.EncryptOAEP(hash, rand.Reader, publicKey, msg, nil)
   744  
   745  	if err1 != nil {
   746  		return "", err1
   747  	}
   748  
   749  	// return encrypted value
   750  	return util.ByteToHex(cipherText), nil
   751  }
   752  
   753  // RsaPrivateKeyDecrypt will decrypt rsa public key encrypted data using its corresponding rsa private key
   754  //
   755  // privateKeyHexOrPem = can be either HEX or PEM
   756  func RsaPrivateKeyDecrypt(data string, privateKeyHexOrPem string) (string, error) {
   757  	// data to decrypt must exist
   758  	if len(data) == 0 {
   759  		return "", errors.New("Data To Decrypt is Required")
   760  	}
   761  
   762  	// get private key
   763  	var privateKey *rsa.PrivateKey
   764  	var err error
   765  
   766  	if util.Left(privateKeyHexOrPem, 27) == "-----BEGIN PRIVATE KEY-----" && util.Right(privateKeyHexOrPem, 25) == "-----END PRIVATE KEY-----" {
   767  		// get private key from pem text
   768  		privateKey, err = rsaPrivateKeyFromPem(privateKeyHexOrPem)
   769  	} else {
   770  		// get private key from hex
   771  		privateKey, err = rsaPrivateKeyFromHex(privateKeyHexOrPem)
   772  	}
   773  
   774  	if err != nil {
   775  		return "", err
   776  	}
   777  
   778  	// convert hex data into byte array
   779  	msg, err1 := util.HexToByte(data)
   780  
   781  	if err1 != nil {
   782  		return "", err1
   783  	}
   784  
   785  	// create hash
   786  	hash := sha256.New()
   787  
   788  	// decrypt
   789  	plainText, err2 := rsa.DecryptOAEP(hash, rand.Reader, privateKey, msg, nil)
   790  
   791  	if err2 != nil {
   792  		return "", err2
   793  	}
   794  
   795  	// return decrypted value
   796  	return string(plainText), nil
   797  }
   798  
   799  // RsaPrivateKeySign will sign the plaintext data using the given private key,
   800  // NOTE: data must be plain text before encryption as signature verification is against plain text data
   801  // signature is returned via hex
   802  //
   803  // privateKeyHexOrPem = can be either HEX or PEM
   804  func RsaPrivateKeySign(data string, privateKeyHexOrPem string) (string, error) {
   805  	// data is required
   806  	if len(data) == 0 {
   807  		return "", errors.New("Data To Sign is Required")
   808  	}
   809  
   810  	// get private key
   811  	var privateKey *rsa.PrivateKey
   812  	var err error
   813  
   814  	if util.Left(privateKeyHexOrPem, 27) == "-----BEGIN PRIVATE KEY-----" && util.Right(privateKeyHexOrPem, 25) == "-----END PRIVATE KEY-----" {
   815  		// get private key from pem text
   816  		privateKey, err = rsaPrivateKeyFromPem(privateKeyHexOrPem)
   817  	} else {
   818  		privateKey, err = rsaPrivateKeyFromHex(privateKeyHexOrPem)
   819  	}
   820  
   821  	if err != nil {
   822  		return "", err
   823  	}
   824  
   825  	// convert data to byte array
   826  	msg := []byte(data)
   827  
   828  	// define hash
   829  	h := sha256.New()
   830  	h.Write(msg)
   831  	d := h.Sum(nil)
   832  
   833  	signature, err1 := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, d)
   834  
   835  	if err1 != nil {
   836  		return "", err1
   837  	}
   838  
   839  	// return signature
   840  	return util.ByteToHex(signature), nil
   841  }
   842  
   843  // RsaPublicKeyVerify will verify the plaintext data using the given public key,
   844  // NOTE: data must be plain text before encryption as signature verification is against plain text data
   845  // if verification is successful, nil is returned, otherwise error is returned
   846  //
   847  // publicKeyHexOrPem = can be either HEX or PEM
   848  func RsaPublicKeyVerify(data string, publicKeyHexOrPem string, signatureHex string) error {
   849  	// data is required
   850  	if len(data) == 0 {
   851  		return errors.New("Data To Verify is Required")
   852  	}
   853  
   854  	// get public key
   855  	var publicKey *rsa.PublicKey
   856  	var err error
   857  
   858  	if util.Left(publicKeyHexOrPem, 26) == "-----BEGIN PUBLIC KEY-----" && util.Right(publicKeyHexOrPem, 24) == "-----END PUBLIC KEY-----" {
   859  		// get public key from pem
   860  		publicKey, err = rsaPublicKeyFromPem(publicKeyHexOrPem)
   861  	} else {
   862  		// get public key from hex
   863  		publicKey, err = rsaPublicKeyFromHex(publicKeyHexOrPem)
   864  	}
   865  
   866  	if err != nil {
   867  		return err
   868  	}
   869  
   870  	// convert data to byte array
   871  	msg := []byte(data)
   872  
   873  	// define hash
   874  	h := sha256.New()
   875  	h.Write(msg)
   876  	d := h.Sum(nil)
   877  
   878  	sig, _ := util.HexToByte(signatureHex)
   879  
   880  	err1 := rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, d, sig)
   881  
   882  	if err1 != nil {
   883  		return err1
   884  	}
   885  
   886  	// verified
   887  	return nil
   888  }
   889  
   890  // RsaPublicKeyEncryptAndPrivateKeySign will encrypt given data using recipient's rsa public key,
   891  // and then using sender's rsa private key to sign,
   892  // NOTE: data represents the plaintext data,
   893  // encrypted data and signature are represented in hex values
   894  //
   895  // recipientPublicKeyHexOrPem = can be either HEX or PEM
   896  // senderPrivateKeyHexOrPem = can be either HEX or PEM
   897  func RsaPublicKeyEncryptAndPrivateKeySign(data string, recipientPublicKeyHexOrPem string, senderPrivateKeyHexOrPem string) (encryptedData string, signature string, err error) {
   898  	encryptedData, err = RsaPublicKeyEncrypt(data, recipientPublicKeyHexOrPem)
   899  
   900  	if err != nil {
   901  		encryptedData = ""
   902  		return "", "", err
   903  	}
   904  
   905  	signature, err = RsaPrivateKeySign(data, senderPrivateKeyHexOrPem)
   906  
   907  	if err != nil {
   908  		encryptedData = ""
   909  		signature = ""
   910  		return "", "", err
   911  	}
   912  
   913  	// return success values
   914  	return encryptedData, signature, nil
   915  }
   916  
   917  // RsaPrivateKeyDecryptAndPublicKeyVerify will decrypt given data using recipient's rsa private key,
   918  // and then using sender's rsa public key to verify if the signature given is a match,
   919  // NOTE: data represents the encrypted data
   920  //
   921  // recipientPrivateKeyHexOrPem = can be either HEX or PEM
   922  // senderPublicKeyHexOrPem = can be either HEX or PEM
   923  func RsaPrivateKeyDecryptAndPublicKeyVerify(data string, recipientPrivateKeyHexOrPem string, signatureHex string, senderPublicKeyHexOrPem string) (plaintext string, verified bool, err error) {
   924  	plaintext, err = RsaPrivateKeyDecrypt(data, recipientPrivateKeyHexOrPem)
   925  
   926  	if err != nil {
   927  		plaintext = ""
   928  		return "", false, err
   929  	}
   930  
   931  	err = RsaPublicKeyVerify(plaintext, senderPublicKeyHexOrPem, signatureHex)
   932  
   933  	if err != nil {
   934  		plaintext = ""
   935  		verified = false
   936  		return "", false, err
   937  	}
   938  
   939  	// return success values
   940  	return plaintext, true, nil
   941  }
   942  
   943  // ================================================================================================================
   944  // RSA+AES DYNAMIC ENCRYPT/DECRYPT HELPERS
   945  // ================================================================================================================
   946  
   947  // RsaAesPublicKeyEncryptAndSign is a simplified wrapper method to generate a random AES key, then encrypt plainText using AES GCM,
   948  // and then sign plain text data using sender's private key,
   949  // and then using recipient's public key to encrypt the dynamic aes key,
   950  // and finally compose the encrypted payload that encapsulates a full envelop:
   951  //
   952  //	<STX>RsaPublicKeyEncryptedAESKeyData + AesGcmEncryptedPayload(PlainTextData<VT>SenderPublicKey<VT>PlainTextDataSignature)<ETX>
   953  //
   954  //	warning: VT is used in encrypted payload as separator, make sure to escape VT if it is to be used inside the plainTextData <<< IMPORTANT
   955  //
   956  // recipientPublicKeyHexOrPem = can be either HEX or PEM
   957  // senderPublicKeyHexOrPem = can be either HEX or PEM
   958  // senderPrivateKeyHexOrPem = can be either HEX or PEM
   959  func RsaAesPublicKeyEncryptAndSign(plainText string, recipientPublicKeyHexOrPem string, senderPublicKeyHexOrPem string, senderPrivateKeyHexOrPem string) (encryptedData string, err error) {
   960  	// validate inputs
   961  	if util.LenTrim(plainText) == 0 {
   962  		return "", errors.New("Data To Encrypt is Required")
   963  	}
   964  
   965  	if util.LenTrim(recipientPublicKeyHexOrPem) == 0 {
   966  		return "", errors.New("Recipient Public Key is Required")
   967  	}
   968  
   969  	if util.LenTrim(senderPublicKeyHexOrPem) == 0 {
   970  		return "", errors.New("Sender Public Key is Required")
   971  	}
   972  
   973  	if util.LenTrim(senderPrivateKeyHexOrPem) == 0 {
   974  		return "", errors.New("Sender Private Key is Required")
   975  	}
   976  
   977  	//
   978  	// generate random aes key for data encryption during this session
   979  	//
   980  	aesKey, err1 := Generate32ByteRandomKey(Sha256(util.NewUUID(), util.CurrentDateTime()))
   981  
   982  	if err1 != nil {
   983  		return "", errors.New("Dynamic AES New Key Error: " + err1.Error())
   984  	}
   985  
   986  	//
   987  	// rsa sender private key sign plain text data
   988  	//
   989  	signature, err2 := RsaPrivateKeySign(plainText, senderPrivateKeyHexOrPem)
   990  
   991  	if err2 != nil {
   992  		return "", errors.New("Dynamic AES Siganture Error: " + err2.Error())
   993  	}
   994  
   995  	//
   996  	// encrypt plain text data using aes key with aes gcm,
   997  	// note: payload format = plainText<VT>senderPublicKeyHex<VT>plainTextSignature
   998  	//
   999  	aesEncryptedData, err3 := AesGcmEncrypt(plainText+ascii.AsciiToString(ascii.VT)+senderPublicKeyHexOrPem+ascii.AsciiToString(ascii.VT)+signature, aesKey)
  1000  
  1001  	if err3 != nil {
  1002  		return "", errors.New("Dynamic AES Data Encrypt Error: " + err3.Error())
  1003  	}
  1004  
  1005  	//
  1006  	// now protect the aesKey with recipient's public key using rsa encrypt
  1007  	//
  1008  	aesEncryptedKey, err4 := RsaPublicKeyEncrypt(aesKey, recipientPublicKeyHexOrPem)
  1009  
  1010  	if err4 != nil {
  1011  		return "", errors.New("Dynamic AES Key Encrypt Error: " + err4.Error())
  1012  	}
  1013  
  1014  	//
  1015  	// compose output encrypted payload
  1016  	// note: aesEncryptedKey_512_Bytes_Always + aesEncryptedData_Variable_Bytes + 64BytesRecipientPublicKeyHashWithSalt of 'TPK@2019' (TPK@2019 doesn't represent anything, just for backward compatibility in prior encrypted data)
  1017  	//       parse first 512 bytes of payload = aes encrypted key (use recipient rsa private key to decrypt)
  1018  	//       parse rest other than first 512 bytes of payload = aes encrypted data, using aes key to decrypt, contains plaintext<VT>senderPublicKey<VT>siganture
  1019  	//
  1020  	encryptedPayload := ascii.AsciiToString(ascii.STX) + aesEncryptedKey + aesEncryptedData + Sha256(recipientPublicKeyHexOrPem, "TPK@2019") + ascii.AsciiToString(ascii.ETX) // wrap in STX and ETX envelop to denote start and end of the encrypted payload
  1021  
  1022  	//
  1023  	// send encrypted payload data to caller
  1024  	//
  1025  	return encryptedPayload, nil
  1026  }
  1027  
  1028  // RsaAesParseTPKHashFromEncryptedPayload will get the public key TPK hash from the embedded encrypted data string
  1029  func RsaAesParseTPKHashFromEncryptedPayload(encryptedData string) string {
  1030  	// strip STX and ETX out
  1031  	data := util.Right(encryptedData, len(encryptedData)-1)
  1032  	data = util.Left(data, len(data)-1)
  1033  
  1034  	// last 64 bytes of the encrypted data is the public key hash
  1035  	data = util.Right(data, 64)
  1036  
  1037  	// get actual tpk key
  1038  	return data
  1039  }
  1040  
  1041  // RsaAesPrivateKeyDecryptAndVerify is a simplified wrapper method to decrypt incoming encrypted payload envelop that was previously encrypted using the RsaAesPublicKeyEncryptAndSign(),
  1042  // this function will use recipient's private key to decrypt the rsa encrypted dynamic aes key and then using the dynamic aes key to decrypt the aes encrypted data payload,
  1043  // this function will then parse the decrypted payload and perform a verification of signature using the sender's public key
  1044  //
  1045  // usage tip: the sender's public key can then be used to encrypt the return data back to the sender as a reply using RsaAesPublicKeyEncryptedAndSign(),
  1046  //
  1047  //	in this usage pattern, only the public key is used in each messaging cycle, while the aes key is dynamically generated each time and no prior knowledge of it is known,
  1048  //	since the public key encrypted data cannot be decrypted unless with private key, then as long as the private key is protected, then the messaging pipeline will be secured,
  1049  //	furthermore, by using sender private key sign and sender public key verify into the message authentication, we further ensure the plain text data is coming from the expected source
  1050  //
  1051  // recipientPrivateKeyHexOrPem = can be either HEX or PEM
  1052  func RsaAesPrivateKeyDecryptAndVerify(encryptedData string, recipientPrivateKeyHexOrPem string) (plainText string, senderPublicKeyHexOrPem string, err error) {
  1053  	// validate inputs
  1054  	if util.LenTrim(encryptedData) <= 578 {
  1055  		return "", "", errors.New("Encrypted Payload Envelop Not Valid: Must Exceed 578 Bytes")
  1056  	}
  1057  
  1058  	if util.Left(encryptedData, 1) != ascii.AsciiToString(ascii.STX) {
  1059  		return "", "", errors.New("Encrypted Payload Envelop Not Valid: No STX Found")
  1060  	}
  1061  
  1062  	if util.Right(encryptedData, 1) != ascii.AsciiToString(ascii.ETX) {
  1063  		return "", "", errors.New("Encrypted Payload Envelop Not Valid: No ETX Found")
  1064  	}
  1065  
  1066  	if util.LenTrim(recipientPrivateKeyHexOrPem) == 0 {
  1067  		return "", "", errors.New("Recipient Private Key is Required")
  1068  	}
  1069  
  1070  	// strip STX and ETX out
  1071  	data := util.Right(encryptedData, len(encryptedData)-1)
  1072  	data = util.Left(data, len(data)-1)
  1073  
  1074  	// parse rsa public key encrypted aes key data
  1075  	aesKeyEncrypted := util.Left(data, 512)
  1076  
  1077  	// parse aes key encrypted data
  1078  	aesDataEncrypted := util.Right(data, len(data)-512)
  1079  
  1080  	// parse tpk hash from aes encrypted data
  1081  	// we don't need the tpk hash for the purpose of this method call
  1082  	// the tpk hash is only used by extracting and matching registry of keys and is used outside of this decrypter
  1083  	aesDataEncrypted = util.Left(aesDataEncrypted, len(aesDataEncrypted)-64)
  1084  
  1085  	//
  1086  	// decrypt aes key encrypted using rsa private key of recipient
  1087  	//
  1088  	aesKey, err1 := RsaPrivateKeyDecrypt(aesKeyEncrypted, recipientPrivateKeyHexOrPem)
  1089  
  1090  	if err1 != nil {
  1091  		return "", "", errors.New("Decrypt AES Key Error: " + err1.Error())
  1092  	}
  1093  
  1094  	//
  1095  	// decrypt aes data using aes key that was just decrypted
  1096  	//
  1097  	aesData, err2 := AesGcmDecrypt(aesDataEncrypted, aesKey)
  1098  
  1099  	if err2 != nil {
  1100  		return "", "", errors.New("Decrypt AES Data Error: " + err2.Error())
  1101  	}
  1102  
  1103  	if util.LenTrim(aesData) <= 1028 {
  1104  		return "", "", errors.New("Decrypted AES Data Not Valid: " + "Expected More Bytes")
  1105  	}
  1106  
  1107  	//
  1108  	// parse decrypted data into elements using VT as separator
  1109  	// expects 3 parts exactly
  1110  	//
  1111  	parts := strings.Split(aesData, ascii.AsciiToString(ascii.VT))
  1112  
  1113  	if len(parts) != 3 {
  1114  		return "", "", errors.New("Decrypted AES Data Not Valid: " + "Expected 3 Parts Exactly, " + util.Itoa(len(parts)) + " Parts Returned Instead" + aesData)
  1115  	}
  1116  
  1117  	plainText = parts[0]
  1118  	senderPublicKeyHexOrPem = parts[1]
  1119  	signature := parts[2]
  1120  
  1121  	if util.LenTrim(plainText) == 0 {
  1122  		plainText = ""
  1123  		senderPublicKeyHexOrPem = ""
  1124  
  1125  		return "", "", errors.New("Decrypted AES Data Not Valid: " + "Empty String Not Expected")
  1126  	}
  1127  
  1128  	if util.LenTrim(senderPublicKeyHexOrPem) < 512 {
  1129  		plainText = ""
  1130  		senderPublicKeyHexOrPem = ""
  1131  
  1132  		return "", "", errors.New("Decrypted AES Data Not Valid: " + "Sender Public Key Not Complete")
  1133  	}
  1134  
  1135  	if util.LenTrim(signature) < 512 {
  1136  		plainText = ""
  1137  		senderPublicKeyHexOrPem = ""
  1138  
  1139  		return "", "", errors.New("Decrypted AES Data Not Valid: " + "Sender Signature Not Complete")
  1140  	}
  1141  
  1142  	//
  1143  	// verify plain text data against signature using sender public key hex
  1144  	//
  1145  	if err3 := RsaPublicKeyVerify(plainText, senderPublicKeyHexOrPem, signature); err3 != nil {
  1146  		plainText = ""
  1147  		senderPublicKeyHexOrPem = ""
  1148  
  1149  		return "", "", errors.New("Decrypted AES Data Not Valid: (Signature Not Authenticated) " + err3.Error())
  1150  	}
  1151  
  1152  	//
  1153  	// decrypt completed successful
  1154  	//
  1155  	return plainText, senderPublicKeyHexOrPem, nil
  1156  }