Dominick,
I generated the key directly without retrieving it from anywhere,encrypted
the key and saved it as a byte array in a shared field/property
and also saved the init vector as a byte array in a shared field/property.
Now I can encrypt, but get a Pkcs7 error upon decryption:
WEB PAGE VB for testing encryption/decryption:
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Public Class EncryptDecryptAesWithDpapi
Inherits System.Web.UI.Page
Dim aesCC As New AesCryptClass
Private Shared _savedIVAsByteArray(31) As Byte
Private Shared _savedCipherText As Byte()
Public Shared Property savedCipherText() As Byte()
Get
Return _savedCipherText
End Get
Set(ByVal Value As Byte())
_savedCipherText = Value
End Set
End Property
Public Shared Property savedIVAsByteArray() As Byte()
Get
Return _savedIVAsByteArray
End Get
Set(ByVal Value As Byte())
_savedIVAsByteArray = Value
End Set
End Property
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
End Sub
Protected WithEvents cleartextTextBox As System.Web.UI.WebControls.TextBox
Protected WithEvents ciphertextTextBox As System.Web.UI.WebControls.TextBox
Protected WithEvents encryptButton As System.Web.UI.WebControls.Button
Protected WithEvents decryptButton As System.Web.UI.WebControls.Button
Protected WithEvents initializationVectorLabel As
System.Web.UI.WebControls.Label
Protected WithEvents initializationVectorTextBox As
System.Web.UI.WebControls.TextBox
Protected WithEvents Textbox1 As System.Web.UI.WebControls.TextBox
Protected WithEvents Textbox2 As System.Web.UI.WebControls.TextBox
Protected WithEvents Button1 As System.Web.UI.WebControls.Button
Protected WithEvents Button2 As System.Web.UI.WebControls.Button
Protected WithEvents receivedIVTextBox As System.Web.UI.WebControls.TextBox
'NOTE: The following placeholder declaration is required by the Web Form
Designer.
'Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
If Not Page.IsPostBack Then
Dim keyGen As New KeyAndEntropyGen
aesCC.key() = keyGen.CreateKey
End If
End Sub
Private Sub encryptButton_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles encryptButton.Click
savedCipherText() = aesCC.Encrypt(cleartextTextBox.Text.TrimEnd())
ciphertextTextBox.Text = Convert.ToBase64String(savedCipherText)
ciphertextTextBox.Text.TrimEnd()
savedIVAsByteArray = aesCC.initVector()
initializationVectorTextBox.Text =
Convert.ToBase64String(aesCC.initVector())
initializationVectorTextBox.Text.TrimEnd()
End Sub
Private Sub decryptButton_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles decryptButton.Click
aesCC.initVector() = savedIVAsByteArray()
receivedIVTextBox.Text = Convert.ToBase64String(savedIVAsByteArray())
cleartextTextBox.Text = aesCC.Decrypt(savedCipherText())
cleartextTextBox.Text.TrimEnd()
End Sub
End Class
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''AES CRYPT CLASS FOR ABOVE:
Imports System
Imports System.IO
Imports System.Text
Imports System.Security.Cryptography
Public Class AesCryptClass
'Dim utf8encoder As New UTF8Encoding
'Attributes to hold key and IV
'Private _key() As Byte =
utf8encoder.GetBytes(Processor.configHandler.AesKeyString())
'Private Shared _key() As Byte =
Convert.FromBase64String(Processor.configHandler.AesKeyString())
Private Shared _key(31) As Byte
' _key =
Convert.FromBase64String(ConfigurationSettings.AppSettings("AeInfo")
'Private Shared _key As Byte() =
Convert.FromBase64String(ConfigurationSettings.AppSettings("AeInfo"))
Private Shared _initVector(31) As Byte
'-------------Public properties to access private attributes
Public Shared Property key() As Byte()
Get
Return _key
End Get
Set(ByVal Value As Byte())
_key = Value
End Set
End Property
Public Shared Property initVector() As Byte()
Get
Return _initVector
End Get
Set(ByVal Value As Byte())
_initVector = Value
End Set
End Property
'--------------------------Function Encrypt---------------------------
Friend Function Encrypt(ByVal plainText As String) As Byte()
'_key =
Convert.FromBase64String(ConfigurationSettings.AppSettings("AeInfo"))
Dim inputInBytes() As Byte = Encoding.UTF8.GetBytes(plainText)
'Create a new AES Service Provider
Dim aesProvider As New RijndaelManaged
'Declare the key size
aesProvider.Padding = PaddingMode.PKCS7
aesProvider.KeySize = 256
aesProvider.BlockSize = 256
aesProvider.GenerateIV()
initVector() = aesProvider.IV
'The ICryptTransform interface uses the Aes crypt provider along with
'encryption key and initialization vector info
'Generate an ICryptoTransform object with the provider create encryptor
Dim cryptoTransform As ICryptoTransform = aesProvider.CreateEncryptor()
' Crypto functions need a stream to output the encrypted info.
'We want to use a memory stream
Dim encryptedStream As New MemoryStream
Dim cryptStream As New CryptoStream(encryptedStream, cryptoTransform,
CryptoStreamMode.Write)
'Write the encrypted information to he stream. Flush the information
'When done to ensure everything is out of the buffer.
cryptStream.Write(inputInBytes, 0, inputInBytes.Length)
cryptStream.FlushFinalBlock()
encryptedStream.Position = 0
'Read the stream back into a byte array and return it
Dim result(encryptedStream.Length - 1) As Byte
encryptedStream.Read(result, 0, encryptedStream.Length)
encryptedStream.Close()
cryptStream.Close()
Return result
End Function
'---------------------------End Function Encrypt
'----------------------------Function Decrypt
Friend Function Decrypt(ByVal inputInBytes() As Byte) As String
'UTFEncoding is used to transform the decrypted Byte Array
'information back into a string.
Dim aesProvider As New RijndaelManaged
aesProvider.Padding = PaddingMode.PKCS7
'Declare the key size
aesProvider.KeySize = 256
aesProvider.BlockSize = 256
'Get the crypto transform object from the provider given the
'key and iv vector
Dim cryptoTransform As ICryptoTransform = aesProvider.CreateDecryptor(key,
initVector())
'Provide memory stream
Dim decryptedStream As New MemoryStream
Dim cryptStream As New CryptoStream(decryptedStream, cryptoTransform,
CryptoStreamMode.Write)
cryptStream.Write(inputInBytes, 0, inputInBytes.Length)
cryptStream.FlushFinalBlock()
decryptedStream.Position = 0
'Read the memory stream and convert it back to a string
Dim result(decryptedStream.Length - 1) As Byte
decryptedStream.Read(result, 0, decryptedStream.Length)
decryptedStream.Close()
cryptStream.Close()
Return Encoding.UTF8.GetString(result)
End Function
End Class
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''Aes Keygen Class:
Imports System
Imports System.IO
Imports System.Text
Imports System.Security.Cryptography
Public Class KeyAndEntropyGen
Friend Function CreateKey() As Byte()
'Create a new AES Service Provider
Dim aesProvider As New RijndaelManaged
'Declare the key size
aesProvider.KeySize = 256
aesProvider.BlockSize = 256
aesProvider.GenerateKey()
Return (aesProvider.Key)
End Function
Friend Function CreateEntropyValue() As String
Dim rng As New RNGCryptoServiceProvider
Dim rng256EntropyByteValue(32) As Byte
rng.GetBytes(rng256EntropyByteValue)
Return Convert.ToBase64String(rng256EntropyByteValue)
End Function
End Class
'''''''''''''''''''''''''''''''''''''''''''''''''''
Dominick Baier said:
Hello Phil C.,
i would encrypt the key first and then convert it to base64 - DPAPI takes
a byte[] as input...
---------------------------------------
Dominick Baier - DevelopMentor
http://www.leastprivilege.com
Hi. I have the following routine that generates an Aes key and
converts it
to a base64 string. The problem is that the returned Base64 string
ALways
contains an '=' or 'Equals sign' as the last character which I
understand
is the result of padding in the algorithm. However, when I take the
generated key, say:
r50h2Iy4pzXb1wpeBEhZie9wM4JmrE6VXUdGk50+RhY=
and encrypt it with the dpapi on my machine, store it, then decrypt it
with
the dpapi,
I get back:
r50h2Iy4pzXb1wpeBEhZie9wM4JmrE6VXUdGk50+RhYA
Any idea why this is happening, and how to correct it? The reason
being
that I seem
to get a decryption iv key size error when using the latter key.
Imports System
Imports System.IO
Imports System.Text
Imports System.Security.Cryptography
Public Class KeyAndEntropyGen
Friend Function CreateKey() As String
'Create a new AES Service Provider
Dim aesProvider As New RijndaelManaged
'Declare the key size
aesProvider.KeySize = 256
aesProvider.BlockSize = 256
aesProvider.GenerateKey()
'Dim ucode8 As New UTF8Encoding
'Return ucode8.GetString(aesProvider.Key)
Return Convert.ToBase64String(aesProvider.Key)
'Return unicode string because string is used in webconfig
End Function
Friend Function CreateEntropyValue() As String
Dim rng As New RNGCryptoServiceProvider
Dim rng256EntropyByteValue(32) As Byte
rng.GetBytes(rng256EntropyByteValue)
Return Convert.ToBase64String(rng256EntropyByteValue)
End Function
End Class