Link to home
Start Free TrialLog in
Avatar of jimseiwert
jimseiwertFlag for United States of America

asked on

Vb.net Encryption

We have code that encrypts passwords for us that an ex developer wrote. We need to decrypt passwords from our database. Can someone head me down the path of how to do this.

Thank you
Public Function encrypt_adage_pw(ByRef inp_str As String) As String
		Dim change_numer As Short
		'Dim inp_str As String
		Dim passwd As String
		Dim status As Short
		Dim seed As Short
		Dim encrypt_key As New VB6.FixedLengthString(62)
		Dim encrypt_len As Short
		Dim i As Short
		Dim inp_len As Short
		Dim acc_tot As Short
		Dim no_of_chars As Short
		Dim ord_inp_char As Short
		Dim op_char As String
		Dim ord_op_char As Short
		Dim decmal As Short
		Dim hex_str As String
		Dim change_number As Short
		'inp_str = Text1.Text
		
		change_number = 2
		encrypt_key.Value = "bDf&3Rt]xQ5!M\sqO/>kGNArm9:iX@(0+S""$ec[ZpHJy}zgVwoLvTK2<=4dFnEWhY1|aPU8)7^lB-jC{6.;`#u*_%,?~I"
		no_of_chars = Len(encrypt_key.Value)
		encrypt_len = 8
		
		If Len(inp_str) < 8 Then
			inp_str = New String(" ", 8 - Len(inp_str))
		End If
		
		inp_len = Len(inp_str)
		If inp_len = 0 Then
			Exit Function
		End If
		
		i = 1
		While i <= inp_len
			
			decmal = 0
			hex_str = (Right(Left(inp_str, i), 1))
			decmal = Asc(hex_str)
			seed = seed + decmal
			i = i + 1
		End While
		hex_str = " "
		decmal = 0
		
		acc_tot = seed
		passwd = ""
		i = 1
		While i <= encrypt_len
            ord_inp_char = i Mod inp_len
			If ord_inp_char = 0 Then
				ord_inp_char = inp_len
			End If
			decmal = 0
			hex_str = Right(Left(inp_str, ord_inp_char), 1)
			decmal = Asc(hex_str)
			acc_tot = acc_tot + decmal + i + ord_inp_char
			ord_op_char = (acc_tot Mod no_of_chars) + 1
			op_char = Right(Left(encrypt_key.Value, ord_op_char), 1)
			passwd = Trim(passwd) & op_char
			i = i + 1
		End While
		encrypt_adage_pw = passwd

Open in new window

Avatar of Bob Learned
Bob Learned
Flag of United States of America image

Hmmm...

1) .NET has some find encryption algorithms.

2) This looks like VB6 code that got migrated to VB.NET.

3) Are you committed to this hand-crafted encryption algorithm.

4) Do you know that .NET assemblies can be disassembled very easily, so that using key information in the code can be very easily discovered (if it matters)?

Bob
Avatar of jimseiwert

ASKER

Yes this was vb6 code that was migrated,

I am not so much commited to this hand crafted style but the issue i have is there is another app that decrypts the password so it need to match

I did not know that the key could be discovered once it was complied into an exe.

There is a jni dll that encrypts the password but the problem with that it is a java dll. If i could use that to encrypt and decrypt that would be ideal
I believe that there are ways to interop between Java classes, and C#, so you should be able to do that with VB.NET also.

Java - C# interop
http://www.velocityreviews.com/forums/t140810-java-c-interop.html

Bob
hex_str = (Right(Left(inp_str, i), 1))
hex_str = Right(Left(inp_str, ord_inp_char), 1)
op_char = Right(Left(encrypt_key.Value, ord_op_char), 1)

is easier understood as:
hex_str = (Mid$(inp_str, i, 1))
hex_str = (Mid$(inp_str, ord_inp_char, 1))
op_char = (Mid$(encrypt_key.Value, ord_op_char, 1))

Basically, these statements are selecting one character from a string variable with the character's position determined by the value of a looping variable.

==================
I'm not sure that this is an encryption.  It might be a variable length hash, with a minimum of eight characters.

I'm not sure if more than eight characters of the inp_str parameter are even touched.
What reason has been given for this request?  Until I get more information, I object.
because the issue was never resolved. All solutions were attempted and failed. This was encryption issue and we were not able to decrypt the key. unless you have a different solution attempt
1. It appears as though you have not supplied the entire function's code.  I won't start any analysis based upon partial code.  Please post in a snippet.

That is the code, only one was left out by mistake and that was end function
Do not delete this just yet.

1. I confirmed my initial suspicions that this is a quasi-hashing function.  It always returns a fixed-length (8) string.

2.  If any of the original passwords was less than 8 characters, you can use ANY character string for the following 'encrypted' passwords found in your database:
Len    PWD
7       3Z\L:&yA
6       e5gAn[Od
5       tJ><+!v0
4       [MLX3}mt
3       x}Gnp/dZ
2       psT(52+M
1       5gAbJmxo

=============================
3. It should be fairly easy to approach the password reconstruction from the algorithm or by a brute-force method.

4. Only the first eight characters are used to directly map into the output string, although the 'seed' (initial value for running total) is calculated from the sum of all the input string characters' ASCII values.

Gotta run now.  Post more later.
addendum
2. for zero-length passwords, you should see
JO2+M=p:
in your database.
Since the initialization literal is longer than the defined 62 string length, the TRUE 'encryption' key is:
bDf&3Rt]xQ5!M\sqO/>kGNArm9:iX@(0+S"$ec[ZpHJy}zgVwoLvTK2<=4dFnE

Note: I've removed the quote delimiters from above and consolidated the doubled-quote in the middle of the literal to show readers the actual string from which the password is constructed.
Once you have elimiated all the database passwords that are the result of sub-eight (length) plaintext passwords, I would approach the problem as follows:
1. have all of your generated passwords begin with a space character.  The choice of the initial character is really up to you.  
Note: The lowest ASCII valued character in the 'encryption key' is 33, which is one greater than the space character.

2. calculate the position of each database password character within the 'encryption key' string.

3. calculate the differences between each character's position (2) MOD 62

4. for each character difference (3), subtract 2 times the position, starting with the second position.
Example:
Posn     Subtract
2           4
3           6
4           8
5           10
6           12
7           14
8           16

5. use these differences (4) to calculate the next characters in the sequence, MOD 62

6. Add the ASCII values of these (5) characters

(AS NEEDED)
7. add character(s) to the end of the password so that the first character changes from a space to the actual first character in the database password string.
I can not eliminate all the database passwords another application that I did not code for uses this database and has the same type of password encryption and decription.
I'm not asking you to 'eliminate' the passwords.  You can use any sub-eight-length password for any entry where the database contains one of the items listed in my prior comment.  

You only need to concern yourself with 'decrypting' the database items that do NOT match one of the strings I listed in my prior comment.  That is the meaning of 'eliminated' in this case -- do not concern yourself with any of these items (they are trivial).
I kind of get where you are going. Can you please provide more detail on steps 2 and 3 and perhaps provide a detail example
?
I'm still working on a simple-to-use solution.  The one I suggested didn't give the correct results when I tested it.  Be patient.
ok, thank you
ASKER CERTIFIED SOLUTION
Avatar of aikimark
aikimark
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@jimseiwert

How is this solution working out for you?
Sorry, i was unable to test until today. The encrypt looks correct as long as the password is greate then 8 which you said. Now i am just trying to get it to match with less then 8

The get password is comming out a little weird. Below is the upgraded code from visual studio with the warnings it provides.

When i set the encrypt password to 12345678 the encrypted is set to c@mAri"} whicj is correct
When i run the getpassword on c@mAri"} it returns an error regarding the start cn not be set to 1 for the instr method inside of StringSequence

so when i change i to start at 1 it returns the follwoing password #2345678Z

Any thoughts?
   Public Function GetPWD(ByRef parmCtext As String, Optional ByRef pDebug As Boolean = False) As String
        'Returns plaintext for 'encrypted' text
        Dim P As String
        Dim C As String
        Dim V As Object
        Dim lngLoop As Integer
        Dim lngSubtract As Integer
        Dim RunningSum As Integer
        Dim CharAsc As Integer
        Dim lngCurrentMod62 As Integer
        Dim lngCharSum As Integer
 
        C = parmCtext
        'UPGRADE_WARNING: Couldn't resolve default property of object StringSequence(). Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
        'UPGRADE_WARNING: Couldn't resolve default property of object V. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
        V = StringSequence(C)
        If pDebug Then
            Debug.Print(New String("_", 20))
            Debug.Print(C)
            For lngLoop = LBound(V) To UBound(V)
                'UPGRADE_WARNING: Couldn't resolve default property of object V(). Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
                Debug.Print(VB6.TabLayout(lngLoop, V(lngLoop), Mid(encrypt_key, V(lngLoop), 1)))
            Next
        End If
        RunningSum = 0
        For lngLoop = 1 To 8
            For CharAsc = 32 To 105
                'UPGRADE_WARNING: Couldn't resolve default property of object V(lngLoop). Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
                If ((RunningSum + CharAsc + (2 * lngLoop)) Mod 62) + 1 = V(lngLoop) Then
                    P = P & Chr(CharAsc)
                    Exit For
                End If
            Next
            RunningSum = RunningSum + CharAsc + (2 * lngLoop)
        Next
        lngCharSum = CharSum(P)
        For CharAsc = 32 To 105
            If (lngCharSum + CharAsc) Mod 62 = 0 Then
                P = P & Chr(CharAsc)
                lngCharSum = lngCharSum + CharAsc
                Exit For
            End If
        Next
        GetPWD = P
    End Function
 
 
    Public Function encrypt_adage_pw_new(ByRef inp_str As String) As String
 
        'Rewritten function only works on strings of length 8 or greater
        Dim change_numer As Short 'Short
        Dim passwd As String
        Dim status As Short 'Short
        Dim seed As Short 'Short
        Dim encrypt_len As Short 'Short
        Dim i As Short 'Short
        Dim inp_len As Short 'Short
        Dim acc_tot As Short 'Short
        Dim no_of_chars As Short 'Short
        Dim ord_inp_char As Short 'Short
        Dim op_char As String
        Dim ord_op_char As Short 'Short
        Dim decmal As Short 'Short
        Dim hex_str As String
        Dim change_number As Short 'Short
 
        change_number = 2
        no_of_chars = Len(encrypt_key)
        encrypt_len = 8
 
        If Len(inp_str) < 8 Then
            inp_str = New String(" ", 8 - Len(inp_str)) & inp_str
        End If
 
        inp_len = Len(inp_str)
        If inp_len = 0 Then
            Exit Function
        End If
 
        seed = CharSum(inp_str)
 
        hex_str = " "
        decmal = 0
 
        acc_tot = seed
        passwd = ""
        For i = 1 To encrypt_len
            decmal = Asc(Mid(inp_str, i, 1))
 
            acc_tot = acc_tot + decmal + (i * 2)
            '            works when string lengths >= 8
 
            ord_op_char = (acc_tot Mod no_of_chars) + 1
            op_char = Mid(encrypt_key, ord_op_char, 1)
            passwd = Trim(passwd) & op_char
        Next
 
        encrypt_adage_pw_new = passwd
    End Function
 
 
    Public Function StringSequence(ByRef parmString As String) As Object
        'Returns byte array of characters' positions in encrypt_key string
        Dim i As Short 'Short
        Dim b() As Byte
 
        'UPGRADE_WARNING: Lower bound of array b was changed from 1 to 0. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="0F1C9BE1-AF9D-476E-83B1-17D43BECFF20"'
        ReDim b(Len(parmString))
        For i = LBound(b) + 1 To UBound(b)
            b(i) = InStr(1, encrypt_key, Mid(parmString, i, 1), CompareMethod.Binary)
        Next
 
        'UPGRADE_WARNING: Couldn't resolve default property of object StringSequence. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
        StringSequence = VB6.CopyArray(b)
    End Function
 
 
    Public Function CharSum(ByRef parmString As String) As Integer
        'Returns sum of string's ASCII values
        Dim lngLoop As Integer
        Dim lngLen As Integer
        Dim lngSum As Integer
        lngLen = Len(parmString)
        For lngLoop = 1 To lngLen
            lngSum = lngSum + Asc(Mid(parmString, lngLoop, 1))
        Next
        CharSum = lngSum
    End Function

Open in new window

Are you initializing the encrypt_key?

I forgot to create the solution in VB classic that would correctly upgrade to VB.Net.  The problem you encountered is because arrays must have zero origin (LBOUND) in .Net.  I'll correct this and repost.

There are 62 different string combinations that will translate into every password in your database.  Your "12345678" password is equivalent to "#2345678Z" as far as the encrypt_adage_pw_new() function is concerned.
<quote>
There are 62 different string combinations that will translate into every password in your database.  Your "12345678" password is equivalent to "#2345678Z" as far as the encrypt_adage_pw_new() function is concerned.
</quote>

I am not sure i follow that statement  the function encrypt_adage_pw_new()  will convert the string of 12345678 to c@mAri"} which is correct the issue is with decrypting it it will translate c@mAri"} to @2345678Z when it should be 12345678
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Ok i see what you are saying even though it returns a different subset the ending value is the same.

I tested your solution and it worked.

Thank you for all your help in this long and trying post. I know i was not the easiest appetence

Now this post can be closed...YAYYYYYY
Thank you for the points and sticking with this discussion past your early exasperation point.  Now you know that patience pays great dividends.