SoFunction
Updated on 2025-03-05

Detailed explanation of examples of Golang implementing password encryption

When storing passwords, the database cannot be stored in plain text, and needs to be encrypted and stored.

There are many types of encryption algorithms, such as: symmetric encryption, asymmetric encryption, hashing algorithms, password derivation, etc.

Before encryption, we need to generate some random numbers, which are called salt

What is salt? Why do you need salt?

Salt is a parameter in an encryption algorithm. It is a random number used to increase the difficulty of cracking passwords.

Think of the password as a dish. Salt is the seasoning, and without seasoning, it is the original dish. If the seasoning is added, the taste of the dish will be different.

In other words, the amount of salt will affect the encryption result. If salt is not used, then the same password will have the same encryption result, so it will be easily cracked.

There are many ways to generate salt, such as: random numbers, timestamps, etc.

Here we use random numbers as an example:

  • Define a string containing all possible characters
  • According to the length of the incoming, generate a slice and fill it with random numbers
  • Iterate through this slice, take out the random number, then take the remainder of the string length, get an index, and then put the corresponding characters of this index into the slice
  • Return to this slice (this slice is salt)
func generateSalt(length int) []byte {
  const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
  salt := make([]byte, length)
  (salt)
  for key, val := range salt {
    salt[key] = alphanum[val%byte(len(alphanum))]
  }
  return salt
}

After generating salt, we can encrypt the password

Encrypted passwords should be usedConvert to string

salt := generateSalt(16)
encoded := ([]byte("uccs"), salt, 100, 32, )
encodedPwd := (encodedPwd)

Because this encryption algorithm is irreversible, that is, you cannot use the encrypted password to invert the original password

So when the user enters the password, how do you know if the password is correct?

Therefore, when storing the encrypted password, the salt and encryption algorithm parameters must also be stored.

The one used here ispbkdf2The algorithm, its parameters are: original password, salt, iteration number, key length, hash algorithm

So the password for the data that ends up exists is:

pwd := ("%s$%s$%d$%d$%s", encodedPwd, salt, 100, 32, "pbkdf2-sha256")

In this way, when verifying the password, you can use these parameters to encrypt the password entered by the user and then compare it with the password stored in the database. If the password is the same, it means that the password is correct.

Knowledge Supplement

MD5 encryption

package main
import (
    "crypto/md5"
    "encoding/hex"
    "fmt"
    "io"
)
func main() {
    h := ()
    (h, "123456")
    sum := (nil)
    ((sum[:]))
    // e10adc3949ba59abbe56e057f20f883e
}

Caesar password encryption

package main
import (
	"fmt"
	"strings"
)
func caesar(r rune, shift int) rune {
	// Shift character by specified number of places.
	// ... If beyond range, shift backward or forward.
	s := int(r) + shift
	if s > 'z' {
		return rune(s - 26)
	} else if s < 'a' {
		return rune(s + 26)
	}
	return rune(s)
}
func main() {
	value := "test"
	(value)
	// Test the caesar method in a func argument to .
	value2 := (func(r rune) rune {
		return caesar(r, 18)
	}, value)
	value3 := (func(r rune) rune {
		return caesar(r, -18)
	}, value2)
	(value2, value3)
	value4 := (func(r rune) rune {
		return caesar(r, 1)
	}, value)
	value5 := (func(r rune) rune {
		return caesar(r, -1)
	}, value4)
	(value4, value5)
	value = "exxegoexsrgi"
	result := (func(r rune) rune {
		return caesar(r, -4)
	}, value)
	(value, result)
}
//Output result//test
//lwkl test
//uftu test
//exxegoexsrgi attackatonce

AES symmetric encryption

package main
import (
	"bytes"
	"crypto/aes"
	"fmt"
	"testing"
)
//ECB mode decryptionfunc ECBDecrypt(crypted, key []byte) ([]byte, error) {
	if !validKey(key) {
		return nil, ("The key length is wrong, the current incoming length is %d",len(key))
	}
	if len(crypted) < 1 {
		return nil, ("The source data length cannot be 0")
	}
	block, err := (key)
	if err != nil {
		return nil, err
	}
	if len(crypted)%() != 0 {
		return nil, ("The length of the source data must be an integer multiple of %d, the current length is: %d",(), len(crypted))
	}
	var dst []byte
	tmpData := make([]byte, ())
	for index := 0; index < len(crypted); index += () {
		(tmpData, crypted[index:index+()])
		dst = append(dst, tmpData...)
	}
	dst, err = PKCS5UnPadding(dst)
	if err != nil {
		return nil, err
	}
	return dst, nil
}
//ECB mode encryptionfunc ECBEncrypt(src, key []byte) ([]byte, error) {
	if !validKey(key) {
		return nil, ("The key length is wrong, the current incoming length is %d",len(key))
	}
	block, err := (key)
	if err != nil {
		return nil, err
	}
	if len(src) < 1 {
		return nil, ("The source data length cannot be 0")
	}
	src = PKCS5Padding(src, ())
	if len(src)%() != 0 {
		return nil, ("The length of the source data must be an integer multiple of %d, the current length is: %d",(), len(src))
	}
	var dst []byte
	tmpData := make([]byte, ())
	for index := 0; index < len(src); index += () {
		(tmpData, src[index:index+()])
		dst = append(dst, tmpData...)
	}
	return dst, nil
}
// PKCS5 fillfunc PKCS5Padding(ciphertext []byte, blockSize int) []byte {
	padding := blockSize - len(ciphertext)%blockSize
	padtext := ([]byte{byte(padding)}, padding)
	return append(ciphertext, padtext...)
}
// Remove PKCS5 fillfunc PKCS5UnPadding(origData []byte) ([]byte, error) {
	length := len(origData)
	unpadding := int(origData[length-1])
	if length < unpadding {
		return nil, ("invalid unpadding length")
	}
	return origData[:(length - unpadding)], nil
}
// Key length verificationfunc validKey(key []byte) bool {
	k := len(key)
	switch k {
	default:
		return false
	case 16, 24, 32:
		return true
	}
}
func TestAes(t *){
	srcData := "hello world !"
	key := []byte("abcdabcdabcdabcdabcdabcdabcdabcd")
	//Test encryption	encData ,err := ECBEncrypt([]byte(srcData),(key))
	if err != nil {
		(())
		return
	}
	//Test decryption	decData ,err := ECBDecrypt(encData,key)
	if err != nil {
		(())
		return
	}
	(string(decData))
}

This is the end of this article about the detailed explanation of Golang's example implementation of password encryption. For more related Golang password encryption content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!