func TestDecryptAES_ECB_Manual(t *testing.T) { key := "YELLOW SUBMARINE" expetedText := "YELLOW SUBMARINE" expetedTextPadding := "YELLOW SUBMARINE!" cipherText := "d1aa4f6578926542fbb6dd876cd20508" cipherTextPadding := "d1aa4f6578926542fbb6dd876cd20508be02542eda8a4ae9cd80e9ce20751237" textBytes := secutils.HexStringToBytes(cipherText) text := DecryptAES_ECB_Manual(textBytes, []byte(key)) if expetedText != secutils.BytesToASCIIString(text) { t.Error("Test Decrypt AES_ECB Manually FAILED !") } fmt.Printf("4. Test DecryptAES_ECB_Manual: %s\n", text) textBytesPadding := secutils.HexStringToBytes(cipherTextPadding) textPadding := DecryptAES_ECB_Manual(textBytesPadding, []byte(key)) if expetedTextPadding != secutils.BytesToASCIIString(textPadding) { t.Error("Test Decrypt AES_ECB Manually + PADDING FAILED !") } fmt.Printf("4. Test DecryptAES_ECB_Manual + PADDING: %s\n", textPadding) }
//####################################################################################################################### //####################################################################################################################### // GOLANG NATIVE CRYPTO FUNCTIONS !!! // USE THESE !!! func DecryptAES_ECB(cipherTextBytes, keyBytes []byte) (string, error) { cipherTextLen := len(cipherTextBytes) mod := cipherTextLen % BlockSize if mod != 0 { panic("ciphertext is not a multiple of the block size") } block, err := aes.NewCipher(keyBytes) if err != nil { panic(err) } numBlocks := cipherTextLen / BlockSize blockBytes := make([]byte, BlockSize) var buffer bytes.Buffer for i := 0; i < numBlocks; i++ { block.Decrypt(blockBytes, cipherTextBytes) buffer.Write(blockBytes) cipherTextBytes = cipherTextBytes[BlockSize:] } decrypedData := buffer.Bytes() if IsPkcs7(decrypedData, BlockSize) { decrypedData = Unpad_Pkcs7(decrypedData, BlockSize) } text := secutils.BytesToASCIIString(decrypedData) return text, nil }
func DecryptAES_CBC(cipherText, keyBytes []byte) (string, error) { fullCipherTextBytes := cipherText //fullCipherTextBytes := secutils.ASCIIStringToBytes(asciiCipherText) // this contains the Cipher Text and the IV //keyBytes := secutils.ASCIIStringToBytes(key) fullCipherTextLen := len(fullCipherTextBytes) // fmt.Printf("Full lenght: %d\n", fullCipherTextLen) // fmt.Printf("Block size: %d\n", blockSize) block, err := aes.NewCipher(keyBytes) if err != nil { panic(err) } // The IV needs to be unique, but not secure. Therefore it's common to // include it at the beginning of the ciphertext. if fullCipherTextLen < BlockSize { panic("ciphertext too short") } iv := fullCipherTextBytes[:BlockSize] cipherTextBytes := fullCipherTextBytes[BlockSize:] cipherTextLen := len(cipherTextBytes) //fmt.Printf("Only cipher text lenght: %d\n", cipherTextLen) mod := cipherTextLen % BlockSize //fmt.Printf("Mod: %d\n", mod) // we need to work out the padding ! // CBC mode always works in whole blocks. if mod != 0 { panic("ciphertext is not a multiple of the block size") } mode := cipher.NewCBCDecrypter(block, iv) decryptedBytes := make([]byte, cipherTextLen) // CryptBlocks can work in-place if the two arguments are the same. mode.CryptBlocks(decryptedBytes, cipherTextBytes) // If the original plaintext lengths are not a multiple of the block // size, padding would have to be added when encrypting, which would be // removed at this point. For an example, see // https://tools.ietf.org/html/rfc5246#section-6.2.3.2. However, it's // critical to note that ciphertexts must be authenticated (i.e. by // using crypto/hmac) before being decrypted in order to avoid creating // a padding oracle. //fmt.Printf("%s\n", cipherTextBytes) text := secutils.BytesToASCIIString(decryptedBytes) return text, nil }