# Blockchain cryptography

Posted by LanceEh on Sat, 09 Oct 2021 15:20:50 +0200

# Chapter I cryptography

## Section 1 Introduction to password

### 1, Why encrypt?

Ensure data security

Xiao Ming – > Xiao Hong:

• After school, I'll see you in the small tree forest at the back door of the school

• Key: + 2

• Ciphertext: let him put in Xueen instead. Run Ruxue. Excuse me, the school. Um, after the school gate is drawn into a small version of the tree version, you can see it

• Decryption: let him put it into Xueen instead. Run Ruxue. Excuse me, the school will draw a small version of the tree version of the school door. Can you see it

• After school, see you at the back door of the school

### 2, Several common encryption algorithms

1. Encoding and decoding

2. Hash encryption

3. Symmetric encryption

4. Asymmetric encryption

5. Digital signature

### 3, Encryption three elements

1. Plaintext / ciphertext

2. Key

3. Encryption algorithm / decryption algorithm

## Section 2 decoding and coding

### 1, Common coding

1. base64:26 lowercase letters, 26 uppercase letters, 10 numbers, /+

2. Base58 (block chain): remove 6 easily confused, remove 0, uppercase O, uppercase I, lowercase L, /, + (64 bits - 6 bits, 58 bits left)

• /, + double click to select

### 2, go implements base64 encoding and decoding

• code

Using: encoding/base64

input := []byte("hello world")

encodeString := base64.StdEncoding.EncodeToString(input)

Use in url:

uEnc := base64.URLEncoding.EncodeToString([]byte(input))

• decode

decodeBytes, err := base64.StdEncoding.DecodeString(encodeString)

Use in url:

uDec, err := base64.URLEncoding.DecodeString(uEnc)

### 3, go realizes base58 encoding, decoding and decoding

base58 coding table

[external chain picture transfer failed. The source station may have anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-xwtlfxqk-1633784349826)( file:///C:/Users/ZHOUWE ~1/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg)]

Character 1 represents 0, character 2 represents 1,..., and character z represents 57

• code

• technological process:

• Convert each byte of the string into ASCII * * (256 base, 2 ^ 8 (binary) * *), and the string is actually a combination of 256 base numbers
• Convert 256 base digits to 10 base digits
• Convert hexadecimal digits to 58 hexadecimal digits (compare hexadecimal digits to 2 hexadecimal digits, constantly take remainder, and 0 is represented by code 1)
• Find the corresponding characters by comparing the 58 base digits with the 58 coding table
• 256 to decimal:

• h:104
• a:97
• 104*256+97=26721
• ```package utils
import (
"fmt"
"math/big"
"bytes"
)
//Binary rule
var b58 = []byte("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")
// base58 encoding
func Base58Encoding(src string) (string) {
// he : 104 101 --> 104*256 + 101 = 26725
// 26725 / 58 =  15 16 17
//1. Convert string to ASCII
src_byte := []byte(src)
// Convert to decimal
i := big.NewInt(0).SetBytes(src_byte)
var mod_slice []byte
// Cyclic residual
//for i.Cmp(big.NewInt(0)) != 0 {
for i.Cmp(big.NewInt(0)) > 0 {
mod := big.NewInt(0)
i58 := big.NewInt(58)
// Surplus
i.DivMod(i,i58,mod)
mod_slice = append(mod_slice, b58[mod.Int64()])
}
// Replace 0 with byte '1'
for _,s := range src_byte {
if s != 0 {
break
}
mod_slice = append(mod_slice, byte('1'))
}
// Invert byte array
//ret_mod_slice := ReverseByteArr(mod_slice)
ret_mod_slice := ReverseByteArr2(mod_slice)
fmt.Println(ret_mod_slice)
return string(ret_mod_slice)
}

// byte array inversion method
func ReverseByteArr(b []byte) []byte{
for i:=0; i<len(b)/2;i++ {
b[i],b[len(b)-1-i] = b[len(b)-1-i],b[i]
}
return b
}
// byte array inversion mode 2
func ReverseByteArr2(b []byte) []byte{
for i,j:=0,len(b)-1;i<j;i,j = i+1,j-1{
b[i] ,b[j] = b[j],b[i]
}
return b
}
- decode
// base58 decoding (reverse the encoding process)
func Base58Decoding(src string) string{
// Convert to byte array
src_byte := []byte(src)
// What you get here is decimal
ret := big.NewInt(0)
for _, b := range src_byte {
i := bytes.IndexByte(b58,b)
fmt.Println(i)
// Ride back
ret.Mul(ret,big.NewInt(58))
}
return string(ret.Bytes())
}
```

## Section 3 hash algorithm

### 1, Characteristics

**Irreversible: * * the original data cannot be recovered from a hash value, and the hash is not encrypted

**Uniqueness: * * there can only be one hash for a specific data, and this hash is unique

Tamper proof: changing a byte in the input data results in a completely different hash value

Registration: account and password. The password stored in the database is md5 encrypted

### 2, Common hash algorithms

• MD4
• MD5
• hash1
• sha224
• sha256
• sha384
• sha512

Performance: MD4 > MD5 > sha224 > sha256 > sha384 > SHA512

Memory consumption: MD5 > MD4 > SHA512 > sha384 > sha256 = sha224

It is recommended to use sha256 normally, with reliable security and low resource consumption.

### 3, go to implement MD4 encryption

```src_byte := []byte(src)
//md4 calculation
md4_new := md4.New()
md4Bytes := md4_new.Sum(src_byte)
md4String := hex.EncodeToString(md4Bytes)
```

### 4, go implements MD5 encryption

```src_byte := []byte(src)
//md5 calculation
md5_new := md5.New()
md5Bytes := md5_new.Sum(src_byte)
md5String := hex.EncodeToString(md5Bytes)
```

### 5, go implement SHA256 encryption

```func GenSha256(src string) string {
src_byte := []byte(src)
hash := sha256.New()
sha256Bytes := hash.Sum(src_byte)
sha256String := hex.EncodeToString(sha256Bytes[:])
return sha256String
}
```

## Section 4 symmetric encryption

### 1, Characteristics

Encryption and decryption use the same key

Two way guarantee of data privacy, that is, encryption and decryption can not disclose the password

High encryption efficiency, suitable for larger data encryption

### 3, Shortcomings

The safety is relatively asymmetric and low

### 4, Specific encryption method

#### 1. AES encryption

• AES-128 encryption: key length 16 bytes
• AES-192 encryption: key length 24 bytes
• AES-256 encryption: key length 32 bytes
```package utils
import (
"crypto/aes"
"fmt"
"bytes"
"encoding/base64"
"errors"
)
//The key can be 16, 24 or 32 bits
var key []byte = []byte("hallenhallenhall") //The key is lowercase and cannot be referenced by other packages (here is the key)
// Fill in the password length based on block.BlockSize(). The password length must be an integer multiple of block.BlockSize()
// Assuming that the password length is 16, the block length is 13, and the number of fillers is 16-13 = 10
pad_num := block_size - len(src_byte) % block_size
src_byte = append(src_byte, ret...) //Splicing ret... Is to take all the values in the array
return src_byte
}
// encryption
func AesEncoding(src string) (string,error) {
src_byte := []byte(src)
// safer
block,err := aes.NewCipher(key) //block is an object. There are many blocks in it
if err != nil {
return src,err
}
// Password filling. The encrypted string is not enough to be an integer multiple of block.BlockSize. Fill it
dst := make([]byte,len(new_src_byte)) //It is used to store the encrypted results. Slices are used here
block.Encrypt(dst,new_src_byte) //Encrypt dst to store the result, which is a byte array
// base64 encoding
pwd := base64.StdEncoding.EncodeToString(dst)
return pwd,nil
}
// decrypt
func AesDecoding(pwd string) (string,error) {
pwd_byte := []byte(pwd)
pwd_byte,err := base64.StdEncoding.DecodeString(pwd)
if err != nil {
return pwd,err
}
block,err_block := aes.NewCipher(key)
if err_block != nil {
return pwd,err_block
}
dst := make([]byte,len(pwd_byte))
block.Decrypt(dst,pwd_byte) //Decrypt dst to store the result, which is a byte array
// The filled shall be removed
return string(dst),nil
}
//Used to decrypt the filled part
if len(dst) <= 0 {
return dst,errors.New("Incorrect length")
}
// The length to be filled is the length to be filled. If the best value is taken, it must be the length to be filled
}
```

#### 2. des encryption: supports byte length of 8

```package utils
import (
"crypto/des"
"encoding/base64"
)
// Only 8 bytes in length are supported
var des_key []byte = []byte("hallenha")//The key is lowercase and cannot be referenced by other packages (here is the key)
// encryption
func DesEncoding(src string) (string,error) {
src_byte := []byte(src)
block ,err := des.NewCiphe(des_key)
if err != nil {
return src,err
}
dst := make([]byte,len(new_src_byte))
block.Encrypt(dst,new_src_byte)
// base64 encoding
pwd := base64.StdEncoding.EncodeToString(dst)
return pwd,nil
}
// decrypt
func DesDecoding(pwd string) (string,error) {
pwd_byte,err := base64.StdEncoding.DecodeString(pwd)
if err != nil {
return pwd,err
}
block,err_block := des.NewCipher(des_key)
if err_block != nil {
return pwd,err_block
}
dst := make([]byte,len(pwd_byte))
block.Decrypt(dst,pwd_byte)
// The filled shall be removed
return string(dst),nil
}
```

#### 3. 3des encryption - CBC mode, the key length must be 24

```package utils
import (
"crypto/des"
"encoding/base64"
)
// The key of 3des is 24 in length
var tdes_key []byte = []byte("hallenhallenhallenhallen")
// 3des encryption
func TDesEncoding(src string) (string,error) {
src_byte := []byte(src)
block ,err := des.**NewTripleDESCipher**(tdes_key) // And des
if err != nil {
return src,err
}
dst := make([]byte,len(new_src_byte))
block.Encrypt(dst,new_src_byte)
// base64 encoding
pwd := base64.StdEncoding.EncodeToString(dst)
return pwd,nil
}
// 3des decryption
func TDesDecoding(pwd string) (string,error) {
pwd_byte,err := base64.StdEncoding.DecodeString(pwd)
if err != nil {
return pwd,err
}
block,err_block := des.**NewTripleDESCipher**(tdes_key) // And des
if err_block != nil {
return pwd,err_block
}
dst := make([]byte,len(pwd_byte))
block.Decrypt(dst,pwd_byte)
// The filled shall be removed
return string(dst),nil
}
```

## Section V asymmetric encryption

### 1, Characteristics

The encryption and decryption keys are different. There are two keys (public key and private key)

Public key: a public key; Public key encryption, private key decryption

Private key: private key; Private key encryption

Private one-way guarantee, as long as one party does not disclose it, it is no problem

Relatively symmetric encryption with high security

### 3, Shortcomings

Low encryption efficiency, suitable for small data encryption

### 4, Scene analysis

For which party is more important, the party will take the private key

The private key is on the client, and the personal information is saved on the client

The public key is on the server to obtain personal data

If: not established

The public key is in the user's hand

The private key is on the server

1. A and B are two people, and B is only allowed to read the information

Public key in A

Private key in B

Public key in B

Private key in A

### 5, Specific encryption method

RSA: initials of three authors

The message sender uses the other party's public key for encryption, and the message receiver uses its own private key for decryption when receiving the ciphertext

be careful:

• There should be an association between public key and key generation
• Keep the key and public key
```package utils
import (
"crypto/rsa"
"crypto/rand"
"fmt"
"crypto/x509"
"encoding/pem"
"os"
)
// Save the generated public key and key
func SaveRsaKey(bits int) (error){
//privateKey is a pointer structure
if err != nil {
fmt.Println(err)
return err
}
//The public key should be associated with the private key, / / privateKey is a structure
publicKey := privateKey.PublicKey
// Use x509 standard to encode the private key, AsN.1 encoding string
x509_privete := x509.MarshalPKCS1PrivateKey(privateKey)
// Use x509 standard to encode the public key and AsN.1 encodes the string
x509_public := x509.MarshalPKCS1PublicKey(&publicKey)//Here, the parameter is of pointer type
// Encapsulate block structure data for private key
block_private := pem.Block{Type:"private key",Bytes:x509_privete}
// Encapsulate block structure data for public key
block_public := pem.Block{Type:"public key",Bytes:x509_public}
// Create a file to store the private key with the suffix. pem
privateFile,err_pri := os.Create("privateKey.pem")
if err_pri != nil {
return err_pri
}
//defer releases resources and closes the file
defer privateFile.Close()
//Write the private key to the file, block_private is a pointer type, and its content is obtained by taking the address character
pem.Encode(privateFile,&block_private)
// Create a file to store the public key with the suffix. pem
publicFile,err_pub := os.Create("publicKey.pem")
if err_pub != nil {
return err_pub
}
//defer releases resources and closes the file
defer publicFile.Close()
//Write the public key to the file, block_public is a pointer type, and its content is obtained by taking the address character
pem.Encode(publicFile,&block_public)
return nil
}
// encryption
func RsaEncoding(src ,file_path string) ([]byte,error){
src_byte := []byte(src)
// Open file
file,err := os.Open(file_path)
if err != nil {
return src_byte,err
}
// Get file information
file_info,err_info := file.Stat()
if err_info != nil {
return src_byte,err_info
}
// Stores the slice used to read the contents of the file
key_bytes := make([]byte,file_info.Size())
// pem decoding
block,_ := pem.Decode(key_bytes)
// x509 decoding
publicKey ,err_pb := x509.ParsePKCS1PublicKey(block.Bytes)
if err_pb != nil {
return src_byte,err_pb
}
// Encrypt plaintext using public key
if err_ret != nil {
return src_byte,err_ret
}
return ret_byte,nil
}
// decrypt
func RsaDecoding(src_byte []byte,file_path string) ([]byte,error) {
// Open file
file,err := os.Open(file_path)
if err != nil {
return src_byte,err
}
// Get file information
file_info,err_info := file.Stat()
if err_info != nil {
return src_byte,err_info
}
key_bytes := make([]byte,file_info.Size())
// pem decoding
block,_ := pem.Decode(key_bytes)
// x509 decoding
privateKey ,err_pb := x509.ParsePKCS1PrivateKey(block.Bytes)
if err_pb != nil {
return src_byte,err_pb
}
// Decrypt
if err_ret != nil {
return src_byte,err_ret
}
return ret_byte,nil
}
```

## Section VI digital signature

### 1, Introduction to digital signature

Digital signature is equivalent to the signature seal of paper contract

Tamper proof, camouflage proof and denial proof

rsa

• Public key encryption
• Private key decryption

rsa digital signature: (digital signature is opposite to rsa encryption, and has different purposes)

• Private key signature
• Public key verification signature

### 2, go implementation of digital signature algorithm

```package utils
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/pem"
"os"
)
//Save the generated public key and key
func SaveRsaSignKey(bits int)error{
//privateKey is a pointer structure
if err!=nil{
return err
}
//privateKey is a structure. The public key should be associated with the private key
publicKey := privateKey.PublicKey
// Use x509 standard to encode the private key, AsN.1 encoding string
x509_privete := x509.MarshalPKCS1PrivateKey(privateKey)
// The x509 standard is used to encode the public key, AsN.1 encodes the string, and the parameter is a pointer
x509_public := x509.MarshalPKCS1PublicKey(&publicKey)
// Encapsulate block structure data for private key
block_private := pem.Block{Type:"private key",Bytes:x509_privete}
// Encapsulate block structure data for public key
block_public := pem.Block{Type:"public key",Bytes:x509_public}
// Create a file to store the private key with the suffix. pem
privateFile,err_pri := os.Create("privateKey.pem")
if err_pri != nil {
return err_pri
}
//defer releases resources and closes the file
defer privateFile.Close()
//Write the private key to the file, block_private is a pointer type, and its content is obtained by taking the address character
pem.Encode(privateFile,&block_private)
// Create a file to store the public key with the suffix. pem
publicFile,err_pub := os.Create("publicKey.pem")
if err_pub != nil {
return err_pub
}
//defer releases resources and closes the file
defer publicFile.Close()
//Write the public key to the file, block_public is a pointer type, and its content is obtained by taking the address character
pem.Encode(publicFile,&block_public)
return nil
}

//Get private key
func GetPivateKey(file_path string)(*rsa.PrivateKey,error) {
// Open file
file,err := os.Open(file_path)
if err != nil {
return &rsa.PrivateKey{},err
}
// Get file information
file_info,err_info := file.Stat()
if err_info != nil {
return &rsa.PrivateKey{},err_info
}
key_bytes := make([]byte,file_info.Size())
// pem decoding
block,_ := pem.Decode(key_bytes)
// x509 decoding
privateKey ,err_pb := x509.ParsePKCS1PrivateKey(block.Bytes)
if err_pb != nil {
return &rsa.PrivateKey{},err_pb
}
return privateKey,nil
}
//Get public key
func GetPublicKey(file_path string)(*rsa.PublicKey,error){
//Open file
file, err := os.Open(file_path)
if err!=nil{
return &rsa.PublicKey{},err
}
// Get file information
file_info, err_info := file.Stat()
if err_info != nil {
return &rsa.PublicKey{},err_info
}
// Stores the slice used to read the contents of the file
key_bytes := make([]byte,file_info.Size())
// pem decoding
block,_ := pem.Decode(key_bytes)
// x509 decoding
publicKey ,err_pb := x509.ParsePKCS1PublicKey(block.Bytes)
if err_pb != nil {
return &rsa.PublicKey{},err_pb
}
return publicKey,nil
}
//Array signature, using private key
func RsaGetSign(file_path string,src string)([]byte,error){
//Get the private key
privateKey, err := GetPivateKey(file_path)
if err!=nil{
return []byte{},err
}
hash := sha256.New()
src_byte := []byte(src)
hash.Write(src_byte)
sha_bytes := hash.Sum(nil)
//autograph
signPKCS1v15, err_sign := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.*SHA256*, sha_bytes)
if err!=nil{
return []byte{},err_sign
}
return signPKCS1v15,nil
}

//Verify the signature using a public key
func RsaVarifySign(sign []byte,file_path string,src string)(bool,error){
publicKey, err := GetPublicKey(file_path)
if err!=nil{
return false,nil
}
hash := sha256.New()
src_byte := []byte(src)
hash.Write(src_byte)
sha_bytes := hash.Sum(nil)
err_verify := rsa.VerifyPKCS1v15(publicKey, crypto.*SHA256*, sha_bytes, sign)
if err_verify!=nil{
return false,nil
}
return true,nil
}
```

Topics: Blockchain Algorithm