Diffi-Hellman-Schlüsselaustausch in VB.Net

    • VB.NET

    Es gibt 1 Antwort in diesem Thema. Der letzte Beitrag () ist von picoflop.

      Diffi-Hellman-Schlüsselaustausch in VB.Net

      Hi Leute,

      ich zeige euch heute wie ein Diffi-Hellman-Schlüsselaustausch funktioniert. Diese Methode benutzen 2 Kommunikationspartner in einem unsicherem Netz, damit dies keiner abhören kann. D.h. damit könntet ihr verschlüsselte Nachrichten austauschen, ohne das sie gelesen werden können. Ihr dürft sie natürlich nicht so in einem einfachen Client speichern, der kann sehr einfach dekompiliert werden.
      Also guckt euch mal lieber den Wikipedia-Artikel an, der kann das besser erklären : D
      Das Prinzip basiert darauf, das 2 Zahlen ausgetauscht werden können, die einem Abhörer nichts bringen. Die Partner können aber daraus einen Key berechnen. Der Key ist jedes Mal ein anderer -> Man kann ihn auch nicht aus dem Quellcode berechnen
      So als erstes speichern beide Partner 2 konstante Zahlen ab, die bei beiden gleich sein muss! Die eine ist eine Primzahl p, die 2. ist eine sog. Primitivwurzel g, welche kleiner als die Primzahl - 2 sein muss.
      Nehmen wir einfach mal wie im Wiki als Beispiel p = 13 und g = 2.

      VB.NET-Quellcode

      1. 'Bei beiden Partnern
      2. Dim p As Integer = 13
      3. Dim g As Integer = 2

      Als nächstes berechnen die beiden Partner unhabhängig voneinander eine Zufahlszahl a und b gennant

      VB.NET-Quellcode

      1. ' Beim Partner 1
      2. Dim a As Integer = random.Next(1, p-2)
      3. 'Bei Partner 2
      4. Dim b As Integer = random.Next(1, p-2)

      Jetzt rechnen sich die Partner eine eigene Zahl aus, zu a entsprechend A und zu b dann B
      Was Modular_Pow ist, seht ihr unten im Spoiler.

      VB.NET-Quellcode

      1. 'Partner 1
      2. Dim _A As Integer = Modular_Pow(g, a, p)
      3. 'Partner 2
      4. Dim _B As Integer = Modular_Pow(g, b, p)

      So das sind unsere Zahlen die übertragen werden. Jetzt hat Partner 1 die Zahl _B und P2 die Zahl _A
      Daraus können jetzt beide den Key k berechnen, dieser wird aber nicht übertragen!

      VB.NET-Quellcode

      1. 'Partner 1
      2. K = Modular_Pow(_B, a, p)
      3. 'Partner 2
      4. K = Modular_Pow(_A, b, p)

      Jetzt kommt bei beiden das gleiche raus, was man an dieser Formel sehen kann:

      Quellcode

      1. K = B^a mod p = ( g^b mod p)^a mod p = g^(b*a) mod p = g^(a*b) mod p
      2. K = A^b mod p = ( g^a mod p)^b mod p = g^(a*b) mod p

      Sieht jetzt kompliziert aus, aber das müsst ihr euch nicht merken...
      Ich habe auch mal eine ausführlichere Klasse dafür gebastelt:
      Spoiler anzeigen

      VB.NET-Quellcode

      1. Public Class Diffi_Hellman_Key_Exchange
      2. Private p As Long
      3. Private g As Long
      4. Private a As Long
      5. Private _A As Long
      6. Private _B As Long
      7. Private K As Long
      8. Public Function Init(ByVal Prime_Number As Long, ByVal Primitive_Root As Long) As Long
      9. If Not Primitive_Root < (Prime_Number - 2) Then
      10. Return -1
      11. End If
      12. If Not Is_Prime_Number(Prime_Number) Then
      13. Return -1
      14. End If
      15. _B = -1
      16. K = -1
      17. p = Prime_Number
      18. g = Primitive_Root
      19. Dim r As New Random
      20. a = r.Next(1, p - 2)
      21. _A = Modular_Pow(g, a, p)
      22. Return _A
      23. End Function
      24. Public Function Is_Prime_Number(ByVal n As Long) As Boolean
      25. Dim b As Boolean = True
      26. For i As Integer = 2 To Int(Math.Sqrt(n))
      27. If (n Mod i = 0) Then
      28. b = False
      29. Return b
      30. End If
      31. Next i
      32. Return b
      33. End Function
      34. Public Function Modular_Pow(ByVal a As Long, ByVal b As Long, ByVal m As Long) As Long
      35. Dim result As Long = 1
      36. While b > 0
      37. If (b And 1) = 1 Then
      38. result = (result * a) Mod m
      39. End If
      40. b >>= 1
      41. a = (a * a) Mod m
      42. End While
      43. Return result
      44. End Function
      45. Public Function Calc_Key(ByVal Received_Number_B As Long) As Long
      46. _B = Received_Number_B
      47. K = Modular_Pow(_B, a, p)
      48. Return K
      49. End Function
      50. Public ReadOnly Property Prime_Number() As Long
      51. Get
      52. Return p
      53. End Get
      54. End Property
      55. Public ReadOnly Property Primitive_Root() As Long
      56. Get
      57. Return g
      58. End Get
      59. End Property
      60. Public ReadOnly Property Random_Number() As Long
      61. Get
      62. Return a
      63. End Get
      64. End Property
      65. Public ReadOnly Property Calculated_Value_A_To_Send() As Long
      66. Get
      67. Return _A
      68. End Get
      69. End Property
      70. Public ReadOnly Property Key() As Long
      71. Get
      72. Return K
      73. End Get
      74. End Property
      75. Public Property Received_Value_B() As Long
      76. Get
      77. Return _B
      78. End Get
      79. Set(ByVal value As Long)
      80. _B = value
      81. K = Calc_Key(value)
      82. End Set
      83. End Property
      84. Public Sub New()
      85. p = -1
      86. g = -1
      87. a = -1
      88. _A = -1
      89. K = -1
      90. _B = -1
      91. End Sub
      92. End Class


      Ich hoffe ich konnte euch helfen! Das ganze ist natürlich auch in php, c/c++, java usw. verfügbar, das müsst ich euch dann selber machen.

      mfG Nibel

      E: Danke an pico, wurde geändert!

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Nibel“ ()

      Statt Math.Pow(a,b) mod m sollte man allerdings besser dieses verwenden:

      VB.NET-Quellcode

      1. Public Function Modular_Pow(ByVal a As Long, ByVal b As Long, ByVal m As Long) As Long
      2. Dim result As Long = 1
      3. While b > 0
      4. If (b And 1) = 1 Then
      5. result = (result * a) Mod m
      6. End If
      7. b >>= 1
      8. a = (a * a) Mod m
      9. End While
      10. Return result
      11. End Function


      Math.Pow(a,b) wird irgendwann ungenau, da die Zahl in nem Double gespeichert wird und dabei fallen dann irgendwann signifikante Stellen weg. Ab einer bestimmten Größe kommt es außerdem zu einem Fehler, da das Zwischenergebnis (a hoch b) die maximale Größe eines Double überschreitet.