Note the implementation of SM4 encryption and decryption on some slightly larger files. Only the core code is listed here, the rest of the code is not covered, or if you have any questions please check out my previous cryptographic blog

var key = []byte("1234567812345678")
var iv = []byte("1111111122222222")

/* function name: paddingLastGroup specifies the plainText data to fill in the last block of the CBC encryption algorithm: plainText, plaindata blockSize, CBC blockSize The time and creator of the filled plaintext data: 2021-06-15 Yuan_sr */
func paddingLastGroup(plainText []byte, blockSize int) []byte{
	padNum := blockSize - len(plainText) % blockSize
	char := []byte{byte(padNum)}
	newPlain := bytes.Repeat(char, padNum)
	newText := append(plainText, newPlain...)
	return newText
}

/* Function name: unpaddingLastGroup An encryption algorithm in CBC encryption mode that provides the last block of plainText data to fill in: plainText  2021-06-15 Yuan_sr */
func unpaddingLastGroup(plainText []byte) []byte{
	length := len(plainText)
	lastChar := plainText[length - 1]
	number := int(lastChar)
	return plainText[:length - number]
}

/* Function name: sm4Enctrpt Sm4 encryption algorithm to encrypt files Parameter: filePathIn, file key to be encrypted, encryption key Returned value: ciphertext file name Error message Created at and by:  2021-06-17 Yuan_sr */
func sm4Enctrpt(filePathIn string, key []byte) (string, error){

	inFile, err := os.Open(filePathIn)
	iferr ! =nil {
		return "", err
	}
	defer inFile.Close()

	outFile, err := os.Create(encryptFileName)
	iferr ! =nil {
		return "", err
	}
	defer outFile.Close()

	buf := make([]byte, bufferSize)
	// Initializes an underlying encryption algorithm
	block, err := sm4.NewCipher(key)
	iferr ! =nil {
		return "", err
	}
	// Select encryption mode
	blockMode := cipher.NewCBCEncrypter(block, iv)

	for {
		n, err := inFile.Read(buf)
		if err == io.EOF{
			break
		}
		iferr ! =nil&& err ! = io.EOF {return "", err
		}

		// The last segment of data is filled with data
		ifn ! = bufferSize{ groupData := paddingLastGroup(buf[:n], block.BlockSize()) n =len(groupData)
			buf = make([]byte, n)
			buf = groupData
		}
		cipherText := make([]byte, n)
		blockMode.CryptBlocks(cipherText, buf[:n])
		_, err = outFile.Write(cipherText)
		iferr ! =nil {
			return "", err
		}
	}
	//outFile.Write(iv)
	return encryptFileName, nil
}

/* Function name: sm4Decrypt The sm4 decryption algorithm realizes the decryption of files parameters: cipherFile, ciphertext file key, decryption key Returned value: file name error message After decryption Time and creator: 2021-06-17 Yuan_sr */
func sm4Decrypt(cipherFile string, key []byte) (string, error){
	// String processing
	imgTagName := getImgTagName(dvImgName)
	plainFileName := imgTagName + ".tar"
	ifdvOutPath ! =". /" {
		err := os.MkdirAll(dvOutPath, 0755)
		iferr ! =nil {
			return "", err
		}
		plainFileName = dvOutPath + imgTagName + ".tar"
	}

	//1. Create an AES low-level password interface
	block, err := sm4.NewCipher(key)
	iferr ! =nil {
		return "", err
	}
	//2. Select decryption mode
	blockMode := cipher.NewCBCDecrypter(block, iv)
	/ / 3. Decryption
	fr, err := os.Open(dvOutPath + cipherFile)
	iferr ! =nil {
		return "", err
	}
	defer fr.Close()
	fileInfo, err := fr.Stat()
	iferr ! =nil {
		return "", err
	}
	blockNum := fileInfo.Size() / bufferSize
	var num int64
	fw, err := os.Create(plainFileName)
	iferr ! =nil {
		return "", err
	}
	defer fw.Close()
	buf := make([]byte, bufferSize)
	for {
		num += 1
		n, err := fr.Read(buf)
		if err == io.EOF{
			break
		}
		iferr ! =nil&& err ! = io.EOF {return "", err
		}

		plainText := make([]byte, n)
		blockMode.CryptBlocks(plainText, buf[:n])
		// The last segment of data is filled with data
		if num == blockNum + 1{
			plainText = unpaddingLastGroup(plainText)
			n = len(plainText)
		}
		_, err = fw.Write(plainText[:n])
		iferr ! =nil {
			return "", err
		}
	}
	return plainFileName, nil
}
Copy the code