func EncryptAES_CBC_Manual(plainText, key string) []byte { keyBytes := secutils.ASCIIStringToBytes(key) plainTextBytes := secutils.ASCIIStringToBytes(plainText) blocks := len(plainTextBytes) / BlockSize mod := len(plainTextBytes) % BlockSize if mod != 0 { blocks++ } iv := make([]byte, BlockSize) if _, err := io.ReadFull(rand.Reader, iv); err != nil { panic(err) } var buffer bytes.Buffer previousBlock := iv buffer.Write(iv) for block := 0; block < blocks; block++ { // this is the last block which may need padding if block == blocks-1 { start := block * BlockSize data := plainTextBytes[start:] // just make sure it is padded // the Pkcs7 function takes care of double check it originalData := Pkcs7(data, BlockSize) // XOR with the previous block xored := secutils.XorBytes(originalData, previousBlock) cipherBlock := Encrypt_Block(xored, keyBytes) buffer.Write(cipherBlock) } else { start := block * BlockSize end := start + BlockSize // XOR with the previous block originalData := plainTextBytes[start:end] xored := secutils.XorBytes(originalData, previousBlock) // Encrypt with the XORED data and assign the result to the previous block for the next cycle ! cipherBlock := Encrypt_Block(xored, keyBytes) // #### THIS IS REALLY IMPORTANT !!!!! // otherwise it is completely broken !!!! previousBlock = cipherBlock buffer.Write(cipherBlock) } } return buffer.Bytes() }
func DecryptAES_CBC_Manual(cipherTextBytes, keyBytes []byte) []byte { blocks := (len(cipherTextBytes) / BlockSize) - 1 // we have to remove the IV //mod := len(cipherTextBytes) % BlockSize //if mod != 0 { // panic("ciphertext is not a multiple of the block size ") //} iv := cipherTextBytes[:BlockSize] remainingBytes := cipherTextBytes[BlockSize:] previousBlock := iv var buffer bytes.Buffer for block := 0; block < blocks; block++ { blockBytes := remainingBytes[:BlockSize] remainingBytes = remainingBytes[BlockSize:] decryptedBlock := Decrypt_Block(blockBytes, keyBytes) xored := secutils.XorBytes(previousBlock, decryptedBlock) buffer.Write(xored) previousBlock = blockBytes } decryptedBytes := buffer.Bytes() if IsPkcs7(decryptedBytes, BlockSize) { decryptedBytes = Unpad_Pkcs7(decryptedBytes, BlockSize) } return decryptedBytes }