Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Imports System.Numerics
- Public Class clsNLS
- 'Generator
- Private NLS_G() As Byte = {&H2F}
- 'Modulus
- Private NLS_N() As Byte = {&H87, &HC7, &H23, &H85, &H65, &HF6, &H16, &H12, &HD9, &H12, &H32, &HC7, &H78, &H6C, &H97, &H7E, &H55, &HB5, &H92, &HA0, &H8C, &HB6, &H86, &H21, &H3, &H18, &H99, &H61, &H8B, &H1A, &HFF, &HF8}
- Private m_Username As String
- Private m_Password As String
- Private m_Salt() As Byte
- Private m_a() As Byte
- Private m_B() As Byte
- 'random value between 0 and N
- Private Sub Generate_a()
- ReDim m_a(31)
- Do
- For I As Integer = 0 To 31 : m_a(I) = Int(Rnd() * 256) : Next I
- Loop While ByteArrayToBigInt(m_a) > ByteArrayToBigInt(NLS_N)
- End Sub
- Public Sub New(ByVal Username As String, ByVal Password As String)
- m_Username = Username.ToUpper
- m_Password = Password.ToUpper
- Generate_a()
- End Sub
- '256 bit random value sent from server, or generated on account creation
- Public Property Salt As Byte()
- Get
- If IsNothing(m_Salt) Then
- ReDim m_Salt(31)
- For I As Integer = 0 To 31 : m_Salt(I) = Int(Rnd() * 256) : Next I
- End If
- Return m_Salt
- End Get
- Set(ByVal value As Byte())
- m_Salt = value
- End Set
- End Property
- 'Username & password hash, SHA1(s, SHA1(Username, ":", Password))
- Public ReadOnly Property x As Byte()
- Get
- Dim SHAup() As Byte = StandardSHA(m_Username & ":" & m_Password)
- Dim GenX(m_Salt.Length + SHAup.Length - 1) As Byte
- Array.Copy(m_Salt, 0, GenX, 0, m_Salt.Length)
- Array.Copy(SHAup, 0, GenX, m_Salt.Length, SHAup.Length)
- Return StandardSHA(GenX)
- End Get
- End Property
- 'Verifier, g ^ x % N
- Public ReadOnly Property Verifier As Byte()
- Get
- Return BigIntToByteArray(BigInteger.ModPow(ByteArrayToBigInt(NLS_G), ByteArrayToBigInt(x), ByteArrayToBigInt(NLS_N)))
- End Get
- End Property
- 'Client Key, g ^ a % N
- Public ReadOnly Property A As Byte()
- Get
- Return BigIntToByteArray(BigInteger.ModPow(ByteArrayToBigInt(NLS_G), ByteArrayToBigInt(m_a), ByteArrayToBigInt(NLS_N)))
- End Get
- End Property
- 'Server Key
- Public Property B As Byte()
- Get
- Return m_B
- End Get
- Set(ByVal value As Byte())
- m_B = value
- End Set
- End Property
- 'First four bytes of SHA1(B)
- Private ReadOnly Property u As Byte()
- Get
- Dim SHA_B() As Byte = StandardSHA(m_B)
- ReDim Preserve SHA_B(3)
- Array.Reverse(SHA_B)
- Return SHA_B
- End Get
- End Property
- 'Secret, ((N + B - v) % N) ^ (a + u * x) % N
- Public ReadOnly Property S As Byte()
- Get
- Return BigIntToByteArray(BigInteger.ModPow(BigInteger.Remainder(ByteArrayToBigInt(NLS_N) + ByteArrayToBigInt(m_B) - ByteArrayToBigInt(Verifier), ByteArrayToBigInt(NLS_N)), ByteArrayToBigInt(m_a) + ByteArrayToBigInt(u) * ByteArrayToBigInt(x), ByteArrayToBigInt(NLS_N)))
- End Get
- End Property
- 'Password Proof, SHA1(even bytes of S) & SHA1(odd bytes of S)
- Public ReadOnly Property K As Byte()
- Get
- Dim bEven(S.Length / 2 - 1) As Byte
- Dim bOdd(S.Length / 2 - 1) As Byte
- For I As Byte = 0 To S.Length - 1
- If I Mod 2 = 0 Then
- bEven(Math.Floor(I / 2)) = S(I)
- Else
- bOdd(Math.Floor(I / 2)) = S(I)
- End If
- Next I
- Dim SHAEven() As Byte = StandardSHA(bEven)
- Dim SHAOdd() As Byte = StandardSHA(bOdd)
- Dim bK(SHAEven.Length * 2 - 1) As Byte
- For I As Byte = 0 To SHAEven.Length - 1
- bK(I * 2) = SHAEven(I)
- bK(I * 2 + 1) = SHAOdd(I)
- Next I
- Return bK
- End Get
- End Property
- 'Client Password Proof, SHA1(SHA1(g) xor SHA1(N), SHA1(Username), s, A, B, K)
- Public ReadOnly Property M1 As Byte()
- Get
- Dim G_XOR_N() As Byte = BigIntToByteArray(ByteArrayToBigInt(StandardSHA(NLS_G)) Xor ByteArrayToBigInt(StandardSHA(NLS_N)))
- Dim SHA_User() As Byte = StandardSHA(m_Username)
- Dim SHA_HashThis(G_XOR_N.Length + SHA_User.Length + m_Salt.Length + A.Length + m_B.Length + K.Length - 1) As Byte
- Dim lPos As Integer = 0
- Array.Copy(G_XOR_N, 0, SHA_HashThis, lPos, G_XOR_N.Length) : lPos += G_XOR_N.Length
- Array.Copy(SHA_User, 0, SHA_HashThis, lPos, SHA_User.Length) : lPos += SHA_User.Length
- Array.Copy(m_Salt, 0, SHA_HashThis, lPos, m_Salt.Length) : lPos += m_Salt.Length
- Array.Copy(A, 0, SHA_HashThis, lPos, A.Length) : lPos += A.Length
- Array.Copy(m_B, 0, SHA_HashThis, lPos, m_B.Length) : lPos += m_B.Length
- Array.Copy(K, 0, SHA_HashThis, lPos, K.Length) : lPos += K.Length
- Return StandardSHA(SHA_HashThis)
- End Get
- End Property
- 'M2 = SHA1(A, M[1], K)
- Public Function VerifyServerProof(ByVal M2() As Byte) As Boolean
- Dim TmpM2() As Byte = StandardSHA(System.Text.Encoding.GetEncoding(LATIN_1).GetString(A) & System.Text.Encoding.GetEncoding(LATIN_1).GetString(M1) & System.Text.Encoding.GetEncoding(LATIN_1).GetString(K))
- Return BitConverter.ToString(M2) = BitConverter.ToString(TmpM2)
- End Function
- Public Function ValidateServerSignature(ByVal Signature() As Byte, ByVal IPAddress As Net.EndPoint)
- ReDim Preserve Signature(Signature.Length)
- Dim RSA_D As New BigInteger({1, 0, 1, 0})
- Dim RSA_C As New BigInteger(Signature)
- Dim RSA_N As New BigInteger({&HD5, &HA3, &HD6, &HAB, &HF, &HD, &HC5, &HF, &HC3, &HFA, &H6E, &H78, &H9D, &HB, &HE3, &H32,
- &HB0, &HFA, &H20, &HE8, &H42, &H19, &HB4, &HA1, &H3A, &H3B, &HCD, &HE, &H8F, &HB5, &H56, &HB5,
- &HDC, &HE5, &HC1, &HFC, &H2D, &HBA, &H56, &H35, &H29, &HF, &H48, &HB, &H15, &H5A, &H39, &HFC,
- &H88, &H7, &H43, &H9E, &HCB, &HF3, &HB8, &H73, &HC9, &HE1, &H77, &HD5, &HA1, &H6, &HA6, &H20,
- &HD0, &H82, &HC5, &H2D, &H4D, &HD3, &H25, &HF4, &HFD, &H26, &HFC, &HE4, &HC2, &H0, &HDD, &H98,
- &H2A, &HF4, &H3D, &H5E, &H8, &H8A, &HD3, &H20, &H41, &H84, &H32, &H69, &H8E, &H8A, &H34, &H76,
- &HEA, &H16, &H8E, &H66, &H40, &HD9, &H32, &HB0, &H2D, &HF5, &HBD, &HE7, &H57, &H51, &H78, &H96,
- &HC2, &HED, &H40, &H41, &HCC, &H54, &H9D, &HFD, &HB6, &H8D, &HC2, &HBA, &H7F, &H69, &H8D, &HCF, &H0})
- Dim RSA_M As BigInteger = BigInteger.ModPow(RSA_C, RSA_D, RSA_N)
- Return BitConverter.ToString(BigIntToByteArray(RSA_M)).Substring(0, 11) = BitConverter.ToString(CType(IPAddress, System.Net.IPEndPoint).Address.GetAddressBytes())
- End Function
- Private Function ByteArrayToBigInt(ByVal b() As Byte) As BigInteger
- ReDim Preserve b(b.Length)
- Return New BigInteger(b)
- End Function
- Private Function BigIntToByteArray(ByVal bI As BigInteger) As Byte()
- Dim bTmp() As Byte = bI.ToByteArray
- If bTmp(bTmp.Length - 1) = 0 Then ReDim Preserve bTmp(bTmp.Length - 2)
- Return bTmp
- End Function
- End Class
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement