470,632 Members | 2,554 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,632 developers. It's quick & easy.

Decrypting a .Net Encrypted string in VB6

I have a password stored in the Registry encrypted using
System.Security.Cryptography DES Algorithm. I supplied it
a password and a Initialization Vector.

I am trying to decrypt it using the CryptoAPI in VB6. I
am using the CryptDeriveKey to generate a session key from
a password. But it is not working and I am sure the
password is correct.

In .net I supplied an IV, when and how do I do that using
the CryptoAPI? In VB6, I must create a hash object to
hash the password into, what hashing algorithm should be
used? Any other pointers would be helpful!!!
Nov 20 '05 #1
8 4943
Hi, I'm not entirely sure I understand... Are you encrypting a password with
the DES algorithm, using VB.NET, then storing it in the registry, and now
trying to Decrypt it with VB6 and the CryptoAPI?

Also, As for a hashing algorithm... It depends on how secure and legal you
want it to be.

--
HTH,
-- Tom Spink, ‹ber Geek

Woe be the day VBC.EXE says, "OrElse what?"

Please respond to the newsgroup,
so all can benefit

"KRoy" <PE***@PEdge.com> wrote in message
news:04****************************@phx.gbl...
I have a password stored in the Registry encrypted using
System.Security.Cryptography DES Algorithm. I supplied it
a password and a Initialization Vector.

I am trying to decrypt it using the CryptoAPI in VB6. I
am using the CryptDeriveKey to generate a session key from
a password. But it is not working and I am sure the
password is correct.

In .net I supplied an IV, when and how do I do that using
the CryptoAPI? In VB6, I must create a hash object to
hash the password into, what hashing algorithm should be
used? Any other pointers would be helpful!!!

Nov 20 '05 #2

"KRoy" <PE***@PEdge.com> wrote in message
news:04****************************@phx.gbl...
I have a password stored in the Registry encrypted using
System.Security.Cryptography DES Algorithm. I supplied it
a password and a Initialization Vector.
By "password", you mean "Key", right? If not, how did you translate the
"password" into a "key"? Also, there are several methods you can use to
encrypt using this class, and several options as well, and each will affect
the output slightly. Might be worth posting your code so we can tell how
it's being performed.
Another issue is that you appear to be calling the base DES implementation,
which can swap out the actual cipher Provider class based on config
settings.
I am trying to decrypt it using the CryptoAPI in VB6. I
am using the CryptDeriveKey to generate a session key from
a password. But it is not working and I am sure the
password is correct.
Depending on how you encrypted the value in the first place (see my first
comment above), you may or may not be able to use the CryptAPI.
One thing is that in this case, you seem to be derriving a key from a
password, yet you did not state what you are doing with this "password" in
the first paragraph to encrypt the value.
In .net I supplied an IV, when and how do I do that using
the CryptoAPI? In VB6, I must create a hash object to
hash the password into, what hashing algorithm should be
used? Any other pointers would be helpful!!!


The IV is used for FeedBack modes. Straight DES encryption is rather weak
(note that it is no longer used by the government for this reason). All
block cipher algorithms work by transforming your plain text one block at a
time, and the results for each block will always be the same for plain text.
So, if you have a lot of repeating values, you'll get a lot of repeating
encrypted blocks, which attackers can use to analyze and possibly reverse
the encryption key. Therefore, most block cipher implementations also allow
different FeedBack modes. These modes introduce derrived bits from the
previous block into subsequent blocks, so that even repeating blocks will
get different resulting values. However, the first block has no previous
data to feed into it, and that's what the IV is for. If you look up the
CryptDeriveKey function call in the MSDN, you will see this line:

"When keys are generated for symmetric block ciphers, the key by default is
set up in cipher block chaining (CBC) mode with an initialization vector of
zero."

Notice the IV (initialization vector) is automatically set to an all-zero
string.

Honestly, I think the best (or at least easiest) thing is to *NOT* mix .NET
crypto functions and the native CryptoAPI functions.
You can achieve this by creating a COM object in .NET that exposes Encrypt
and Decrypt functions (using the .NET crypto classes internally). Once you
install the .NET assembly and register it, VB6 applications will be able to
interface with it through COM.

-Rob Teixeira [MVP]
Nov 20 '05 #3
Yes, you are correct.
-----Original Message-----
Hi, I'm not entirely sure I understand... Are you encrypting a password withthe DES algorithm, using VB.NET, then storing it in the registry, and nowtrying to Decrypt it with VB6 and the CryptoAPI?

Also, As for a hashing algorithm... It depends on how secure and legal youwant it to be.

--
HTH,
-- Tom Spink, ‹ber Geek

Woe be the day VBC.EXE says, "OrElse what?"

Please respond to the newsgroup,
so all can benefit

"KRoy" <PE***@PEdge.com> wrote in message
news:04****************************@phx.gbl...
I have a password stored in the Registry encrypted using
System.Security.Cryptography DES Algorithm. I supplied it a password and a Initialization Vector.

I am trying to decrypt it using the CryptoAPI in VB6. I
am using the CryptDeriveKey to generate a session key from a password. But it is not working and I am sure the
password is correct.

In .net I supplied an IV, when and how do I do that using the CryptoAPI? In VB6, I must create a hash object to
hash the password into, what hashing algorithm should be
used? Any other pointers would be helpful!!!

.

Nov 20 '05 #4
Yes, you are correct.
-----Original Message-----
Hi, I'm not entirely sure I understand... Are you encrypting a password withthe DES algorithm, using VB.NET, then storing it in the registry, and nowtrying to Decrypt it with VB6 and the CryptoAPI?

Also, As for a hashing algorithm... It depends on how secure and legal youwant it to be.

--
HTH,
-- Tom Spink, ‹ber Geek

Woe be the day VBC.EXE says, "OrElse what?"

Please respond to the newsgroup,
so all can benefit

"KRoy" <PE***@PEdge.com> wrote in message
news:04****************************@phx.gbl...
I have a password stored in the Registry encrypted using
System.Security.Cryptography DES Algorithm. I supplied it a password and a Initialization Vector.

I am trying to decrypt it using the CryptoAPI in VB6. I
am using the CryptDeriveKey to generate a session key from a password. But it is not working and I am sure the
password is correct.

In .net I supplied an IV, when and how do I do that using the CryptoAPI? In VB6, I must create a hash object to
hash the password into, what hashing algorithm should be
used? Any other pointers would be helpful!!!

.

Nov 20 '05 #5
I have decided to P/Invoke the CryptoAPI into my .net
application. However, this seems to be throwing me a new
curve with how to send my plainText (vb string) to the
CryptEncrypt function as pbData. My code is as follows:

<DllImport(CryptDll)> _
Public Shared Function CryptEncrypt _
(ByVal hKey As Integer, _
ByVal hHash As Integer, _
ByVal Final As Boolean, _
ByVal dwFlags As Integer, _
ByRef pdData As String, _
ByRef pdwDataLen As Integer, _
ByVal dwBufLen As Integer) As Boolean
End Function

Public Function Encrypt(dataString as String) as String
..
.... Got hKey (vb Integer) from CryptDeriveKey
..
lResult = CryptEncryptNULL(hKey, 0, True, 0, Nothing,
dataLength, bufLength)
If Not lResult Then
msgResult = MsgBox("Failed")
Else
' Create buffer string to correct size and fill it
with dataString
Dim codedString As Byte() =
System.Text.Encoding.ASCII.GetBytes(dataString)
Dim codedBuffer As Byte() =
System.Text.Encoding.ASCII.GetBytes(Space(dataLeng th))
System.Buffer.BlockCopy(codedString, 0, codedBuffer,
0, codedString.Length)
Dim bufferString As String =
System.Text.Encoding.ASCII.GetString(codedBuffer)
' Now we have string the size of the buffer
dataLength = dataString.Length
bufLength = bufferString.Length
lResult = WinApi.CryptEncrypt(hKey, 0, True, 0,
bufferString, dataLength, bufLength)

On this last line, I get the following error:
"An unhandled exception of
type 'System.NullReferenceException' occurred in
pedge.security.dll

Additional information: Object reference not set to an
instance of an object."

I think this has to do with the function trying to return
the value "ByRef" back into bufferString. In VB6, we
could pass bufferString ByVal to pass the pointer, this
can't be done in vb.net. How can I pass the pointer of
bufferString???
-----Original Message-----

"KRoy" <PE***@PEdge.com> wrote in message
news:04****************************@phx.gbl...
I have a password stored in the Registry encrypted using
System.Security.Cryptography DES Algorithm. I supplied it a password and a Initialization Vector.
By "password", you mean "Key", right? If not, how did you

translate the"password" into a "key"? Also, there are several methods you can use toencrypt using this class, and several options as well, and each will affectthe output slightly. Might be worth posting your code so we can tell howit's being performed.
Another issue is that you appear to be calling the base DES implementation,which can swap out the actual cipher Provider class based on configsettings.
I am trying to decrypt it using the CryptoAPI in VB6. I
am using the CryptDeriveKey to generate a session key from a password. But it is not working and I am sure the
password is correct.
Depending on how you encrypted the value in the first

place (see my firstcomment above), you may or may not be able to use the CryptAPI.One thing is that in this case, you seem to be derriving a key from apassword, yet you did not state what you are doing with this "password" inthe first paragraph to encrypt the value.
In .net I supplied an IV, when and how do I do that using the CryptoAPI? In VB6, I must create a hash object to
hash the password into, what hashing algorithm should be
used? Any other pointers would be helpful!!!
The IV is used for FeedBack modes. Straight DES

encryption is rather weak(note that it is no longer used by the government for this reason). Allblock cipher algorithms work by transforming your plain text one block at atime, and the results for each block will always be the same for plain text.So, if you have a lot of repeating values, you'll get a lot of repeatingencrypted blocks, which attackers can use to analyze and possibly reversethe encryption key. Therefore, most block cipher implementations also allowdifferent FeedBack modes. These modes introduce derrived bits from theprevious block into subsequent blocks, so that even repeating blocks willget different resulting values. However, the first block has no previousdata to feed into it, and that's what the IV is for. If you look up theCryptDeriveKey function call in the MSDN, you will see this line:
"When keys are generated for symmetric block ciphers, the key by default isset up in cipher block chaining (CBC) mode with an initialization vector ofzero."

Notice the IV (initialization vector) is automatically set to an all-zerostring.

Honestly, I think the best (or at least easiest) thing is to *NOT* mix .NETcrypto functions and the native CryptoAPI functions.
You can achieve this by creating a COM object in .NET that exposes Encryptand Decrypt functions (using the .NET crypto classes internally). Once youinstall the .NET assembly and register it, VB6 applications will be able tointerface with it through COM.

-Rob Teixeira [MVP]
.

Nov 20 '05 #6
pdData is an [in/out] parameter. Never pass a .NET String variable to an
unmanaged function that will modify it. .NET strings must remain immutable
(can't be changed). Also, the "real" function prototype defines pdData as a
pointer to a byte array. I suggest you actually define it that way as well -
after all, you already have the byte array buffer, no need to create a
seperate string copy. Also note that DES is a block cipher. That being said,
block ciphers don't return data that is exactly the size of the input (plain
text). For example, if the block is 16 bits (which off the top of my head, i
believe is what DES uses), it will always return data with a size in a
multiple of 16 bits. If the input data length is exactly a multiple of 16
bits, then you'll have no problem, but if it is not, then the returned data
will require a length to the nearest 16-bit block size, plus an additional
full block (which will be padded by the cipher algorithm).

-Rob Teixeira [MVP]
"KRoy" <an*******@discussions.microsoft.com> wrote in message
news:0b****************************@phx.gbl...
I have decided to P/Invoke the CryptoAPI into my .net
application. However, this seems to be throwing me a new
curve with how to send my plainText (vb string) to the
CryptEncrypt function as pbData. My code is as follows:

<DllImport(CryptDll)> _
Public Shared Function CryptEncrypt _
(ByVal hKey As Integer, _
ByVal hHash As Integer, _
ByVal Final As Boolean, _
ByVal dwFlags As Integer, _
ByRef pdData As String, _
ByRef pdwDataLen As Integer, _
ByVal dwBufLen As Integer) As Boolean
End Function

Public Function Encrypt(dataString as String) as String
.
... Got hKey (vb Integer) from CryptDeriveKey
.
lResult = CryptEncryptNULL(hKey, 0, True, 0, Nothing,
dataLength, bufLength)
If Not lResult Then
msgResult = MsgBox("Failed")
Else
' Create buffer string to correct size and fill it
with dataString
Dim codedString As Byte() =
System.Text.Encoding.ASCII.GetBytes(dataString)
Dim codedBuffer As Byte() =
System.Text.Encoding.ASCII.GetBytes(Space(dataLeng th))
System.Buffer.BlockCopy(codedString, 0, codedBuffer,
0, codedString.Length)
Dim bufferString As String =
System.Text.Encoding.ASCII.GetString(codedBuffer)
' Now we have string the size of the buffer
dataLength = dataString.Length
bufLength = bufferString.Length
lResult = WinApi.CryptEncrypt(hKey, 0, True, 0,
bufferString, dataLength, bufLength)

On this last line, I get the following error:
"An unhandled exception of
type 'System.NullReferenceException' occurred in
pedge.security.dll

Additional information: Object reference not set to an
instance of an object."

I think this has to do with the function trying to return
the value "ByRef" back into bufferString. In VB6, we
could pass bufferString ByVal to pass the pointer, this
can't be done in vb.net. How can I pass the pointer of
bufferString???

Nov 20 '05 #7
Thanks! That was a good expaination, however I seem to be
still getting that error with the byte array. Code as
follows:

<DllImport(CryptDll)> _
Public Shared Function CryptEncrypt _
(ByVal hKey As Integer, _
ByVal hHash As Integer, _
ByVal Final As Boolean, _
ByVal dwFlags As Integer, _
ByRef pdData() As Byte, _
ByRef pdwDataLen As Integer, _
ByVal dwBufLen As Integer) As Boolean
End Function

Public Function Encrypt(dataString as String) as String
...
..... Got hKey (vb Integer) from CryptDeriveKey
...
lResult = CryptEncryptNULL(hKey, 0, True, 0, Nothing,
dataLength, bufLength)
If Not lResult Then
msgResult = MsgBox("Failed")
Else
' Create codedBuffer to correct size and fill it
with codedData
Dim codedString As Byte() =
System.Text.Encoding.ASCII.GetBytes(dataString)
Dim codedBuffer As Byte() = New Byte(dataLength - 1)
{}
System.Buffer.BlockCopy(codedString, 0, codedBuffer,
0, codedString.Length)
' Now codedBuffer is sized correctly
dataLength = codedString.Length
bufLength = codedBuffer.Length
lResult = WinApi.CryptEncrypt(hKey, 0, True, 0,
codedBuffer, dataLength, bufLength)

On this last line, I'm still getting the following error:
"An unhandled exception of
type 'System.NullReferenceException' occurred in
pedge.security.dll

Additional information: Object reference not set to an
instance of an object."

-----Original Message-----
pdData is an [in/out] parameter. Never pass a .NET String variable to anunmanaged function that will modify it. .NET strings must remain immutable(can't be changed). Also, the "real" function prototype defines pdData as apointer to a byte array. I suggest you actually define it that way as well -after all, you already have the byte array buffer, no need to create aseperate string copy. Also note that DES is a block cipher. That being said,block ciphers don't return data that is exactly the size of the input (plaintext). For example, if the block is 16 bits (which off the top of my head, ibelieve is what DES uses), it will always return data with a size in amultiple of 16 bits. If the input data length is exactly a multiple of 16bits, then you'll have no problem, but if it is not, then the returned datawill require a length to the nearest 16-bit block size, plus an additionalfull block (which will be padded by the cipher algorithm).

-Rob Teixeira [MVP]
"KRoy" <an*******@discussions.microsoft.com> wrote in messagenews:0b****************************@phx.gbl...
I have decided to P/Invoke the CryptoAPI into my .net
application. However, this seems to be throwing me a new curve with how to send my plainText (vb string) to the
CryptEncrypt function as pbData. My code is as follows:

<DllImport(CryptDll)> _
Public Shared Function CryptEncrypt _
(ByVal hKey As Integer, _
ByVal hHash As Integer, _
ByVal Final As Boolean, _
ByVal dwFlags As Integer, _
ByRef pdData As String, _
ByRef pdwDataLen As Integer, _
ByVal dwBufLen As Integer) As Boolean
End Function

Public Function Encrypt(dataString as String) as String
.
... Got hKey (vb Integer) from CryptDeriveKey
.
lResult = CryptEncryptNULL(hKey, 0, True, 0, Nothing,
dataLength, bufLength)
If Not lResult Then
msgResult = MsgBox("Failed")
Else
' Create buffer string to correct size and fill it
with dataString
Dim codedString As Byte() =
System.Text.Encoding.ASCII.GetBytes(dataString)
Dim codedBuffer As Byte() =
System.Text.Encoding.ASCII.GetBytes(Space(dataLeng th))
System.Buffer.BlockCopy(codedString, 0, codedBuffer,
0, codedString.Length)
Dim bufferString As String =
System.Text.Encoding.ASCII.GetString(codedBuffer)
' Now we have string the size of the buffer
dataLength = dataString.Length
bufLength = bufferString.Length
lResult = WinApi.CryptEncrypt(hKey, 0, True, 0,
bufferString, dataLength, bufLength)

On this last line, I get the following error:
"An unhandled exception of
type 'System.NullReferenceException' occurred in
pedge.security.dll

Additional information: Object reference not set to an
instance of an object."

I think this has to do with the function trying to return the value "ByRef" back into bufferString. In VB6, we
could pass bufferString ByVal to pass the pointer, this
can't be done in vb.net. How can I pass the pointer of
bufferString???

.

Nov 20 '05 #8
Change pdData to ByVal. Like a String, Arrays are references. ByRef will
give you a pointer to a pointer, which is not what you want in this case.

-Rob Teixeira [MVP]
"KRoy" <pe***@pedge.com> wrote in message
news:01****************************@phx.gbl...
Thanks! That was a good expaination, however I seem to be
still getting that error with the byte array. Code as
follows:

<DllImport(CryptDll)> _
Public Shared Function CryptEncrypt _
(ByVal hKey As Integer, _
ByVal hHash As Integer, _
ByVal Final As Boolean, _
ByVal dwFlags As Integer, _
ByRef pdData() As Byte, _
ByRef pdwDataLen As Integer, _
ByVal dwBufLen As Integer) As Boolean
End Function

Nov 20 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by chris | last post: by
10 posts views Thread by Alessandro Bottoni | last post: by
3 posts views Thread by VB Programmer | last post: by
reply views Thread by Mark Moeykens | last post: by
1 post views Thread by Korara | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.