tincho   04-10-2023, 15:34
#1
Hola.
Alguien tiene una función que analice la dureza de una contraseña?

Por ejemplo:

Código:
'' Hardness level

Static Public Function Hardness(s As String) As Byte

  Dim i As Integer

  If InStr(s, "@") > 0 Then
    Inc i
  Endif

  Return i

End

1 Saludo.
vuott   04-10-2023, 16:45
#2
(04-10-2023, 15:34)tincho escribió: la dureza de una contraseña

¿Es decir: "Seguridad de la contraseña" ?
Última modificación: 04-10-2023, 16:50 por vuott.

« Los horizontes perdidos nunca regresan. » (F. Battiato, 1983)

« Las ondas nunca regresan. » (Genesis: Ripples, 1976)

« Vita non suavis esse potest, nec Mors amara. »  (...vuott)
cogier   04-10-2023, 16:59
#3
Le pregunté a Bing AI cómo hacer esto en Gambas. El código que me dio no funcionaba, pero con algunos cambios se me ocurrió esto. El código de Bing está abajo. Como dijo Bing, ¡espero que esto ayude!

Código:
' Gambas class file

Public Sub Form_Open()
  
  ' Example usage:
  CheckPasswordStrength("MyP@ssw0rd")
  
End

Public Sub CheckPasswordStrength(password As String)
  
  Dim length As Integer = Len(password)
  Dim hasLowercase As Boolean = False
  Dim hasUppercase As Boolean = False
  Dim hasDigit As Boolean = False
  Dim hasSpecialChar As Boolean = False
  Dim specialChars As String = "!@#$%^&*()_+-=[]{}|;:,.<>?~"
  
  For i As Integer = 0 To length - 1
    If IsLower(password[i]) Then
      hasLowercase = True
    Else If IsUpper(password[i]) Then
      hasUppercase = True
    Else If IsDigit(password[i]) Then
      hasDigit = True
    Else If InStr(specialChars, password[i]) Then
      hasSpecialChar = True
    End If
  Next
  
  If length < 8 Or Not hasLowercase Or Not hasUppercase Or Not hasDigit Or Not hasSpecialChar Then
    Print "The password is weak."
  Else If length < 12 Then
    Print "The password is moderate."
  Else
    Print "The password is strong."
  End If
  
End Sub


' Public Sub CheckPasswordStrength(password As String)
'     Dim length As Integer = Len(password)
'     Dim hasLowercase As Boolean = False
'     Dim hasUppercase As Boolean = False
'     Dim hasDigit As Boolean = False
'     Dim hasSpecialChar As Boolean = False
'     Dim specialChars As String = "!@#$%^&*()_+-=[]{}|;:,.<>?~"

'     For i As Integer = 0 To length - 1
'         If Char.IsLower(password(i)) Then
'             hasLowercase = True
'         ElseIf Char.IsUpper(password(i)) Then
'             hasUppercase = True
'         ElseIf Char.IsDigit(password(i)) Then
'             hasDigit = True
'         ElseIf specialChars.Contains(password(i)) Then
'             hasSpecialChar = True
'         End If
'     Next

'     If length < 8 Or Not hasLowercase Or Not hasUppercase Or Not hasDigit Or Not hasSpecialChar Then
'         Print "The password is weak."
'     Else If length < 12 Then
'         Print "The password is moderate."
'     Else
'         Print "The password is strong."
'     End If
' End Sub

' ' Example usage:
' CheckPasswordStrength("MyP@ssw0rd")

' This code checks if the given password meets the following criteria:

' Has at least one lowercase letter.
' Has at least one uppercase letter.
' Has at least one digit.
' Has at least one special character (e.g., !, @, #, $, %, ^, &, *, (, ), _, +, -, =, [, ], {, }, |, ;, :, , ., <, >, ?, ~).
' Is at least 8 characters long.
' If the password meets all of these criteria, it is considered strong. If it does not meet all of these criteria but is at least 8 characters long, it is considered moderate. Otherwise, it is considered weak.

' I hope this helps!

He corregido a Bing hasta que ha conseguido que el código funcione, así que espero que produzca mejor código Gambas en el futuro.
Última modificación: 04-10-2023, 17:12 por cogier.
tincho   04-10-2023, 19:13
#4
(04-10-2023, 16:45)vuott escribió: ¿Es decir: "Seguridad de la contraseña" ?

Correcto, una función que mida el nivel de seguridad de una contraseña

(04-10-2023, 16:59)cogier escribió: Le pregunté a Bing AI cómo hacer esto en Gambas. El código que me dio no funcionaba, pero con algunos cambios se me ocurrió esto. El código de Bing está abajo. Como dijo Bing, ¡espero que esto ayude!
Código:
 

Muchas gracias, estoy intentando hacerlo con expresiones regulares, a ver como sale.
Última modificación: 04-10-2023, 19:52 por tincho.

1 Saludo.
Shell   04-10-2023, 23:10
#5
Mmmm.. Rolleyes

Cómo crear una contraseña segura en 4 pasos

"El conocimiento es la mejor inversión que se puede hacer" - Abraham Lincoln
tincho   05-10-2023, 23:59
#6
Este el el código que les propongo:
Código:
'' Password hardness level

Static Public Function Hardness(s As String) As Integer

  Dim i As Integer

  i = Len(s)

  ' Tiene un digito
  If RegExp.Match(s, "[0-9]{2}") Then
    Inc i
  Else
    Dec i
  Endif

  ' Tiene 2 mayúsculas?
  If RegExp.Match(s, "[A-Z]{2}") Then
    Inc i
  Else
    Dec i
  Endif

  ' Tiene 2 minúsculas?
  If RegExp.Match(s, "[a-z]{2}") Then
    Inc i
  Else
    Dec i
  Endif

  ' Tiene 2 símbolos?
  ' If RegExp.Match(s, "^[a-z][A-Z][0-9]") Then
  '   Inc i
  ' Else
  '   Dec i
  ' Endif

  Return i

End
Para un mejor desempeño, falta saber como es la expresión regular para saber si existe algún símbolo en la cadena.

1 Saludo.
tincho   09-10-2023, 01:36
#7
Hola, seguí con el asunto y no encontré ningún estándar con el que contrastar las contraseñas, solo encontré el siguiente sitio:
https://password.es/comprobador/
Como me pareció razonable, intente escribir un código que haga lo mismo, también existe el código JS (es GPL y se puede descargar) pero lo mire solo para ver los rangos de cada nivel: Very Weak, Weak....

Código:
Public Function Hardeness(sPass As String) As Integer

  Dim r As Integer
  Dim o As New JSONCollection
  Dim i As Integer
  Dim p As Integer
  Dim q As Integer = 0
  Dim rep As New JSONCollection
  Dim aCUL As New String[] '' Consecutivas Upper and Lower
  Dim cul As New JSONCollection

  o["chars"] = String.Len(sPass) '' Número de Caracteres
  o["length"] = 8
  o["uppers"] = 0                '' Letras Mayúsculas
  o["lowers"] = 0                '' Letras minúsculas
  o["numbers"] = 0               '' Números
  o["symbols"] = 0               '' Símbolos

  cul.Add(0, "U")
  cul.Add(0, "L")
  cul.Add(0, "N")
  cul.Add(0, "S")

  For i = 1 To String.Len(sPass)
    p = Asc(TextBox1.Text, i)
    If p > 32 And p < 48 Then  ' symbol
      o["symbols"] = o["symbols"] + 1
      aCUL.Add("S")
    Else
      If p > 57 And p < 65 Then
        o["symbols"] = o["symbols"] + 1
        aCUL.Add("S")
      Else
        If p > 64 And p < 91 Then  ' upper
          o["uppers"] = o["uppers"] + 1
          aCUL.Add("U")
        Else
          If p > 96 And p < 123 Then  ' lower
            o["lowers"] = o["lowers"] + 1
            aCUL.Add("L")
          Else
            If p > 47 And p < 58 Then  ' number
              o["numbers"] = o["numbers"] + 1
              aCUL.Add("N")
            Endif
          Endif
        Endif
      Endif
    Endif

    If rep.Exist(CStr(p)) Then
      rep[CStr(p)] = rep[CStr(p)] + 1
    Else
      rep[CStr(p)] = 1
    Endif

  Next

  '' Adiciones
  If o["chars"] > 0 Then
    r = (o["chars"] * 4)

    If o["uppers"] > 0 Then
      r = r + ((o["chars"] - o["uppers"]) * 2)
    Endif

    If o["lowers"] > 0 Then
      r = r + ((o["chars"] - o["lowers"]) * 2)
    Endif

    If o["numbers"] > 0 Then
      r = r + (o["numbers"] * 4)
    Endif

    If o["symbols"] > 0 Then
      r = r + (o["symbols"] * 4)
    Endif

    ' Mitad números o simbolos
    If o["symbols"] + o["numbers"] = (o["chars"] / 2) Then
      r = r + ((o["symbols"] + o["numbers"]) * 2)
    Endif

    ' Requerimientos
    If o["chars"] >= o["length"] Then
      Inc q
    Endif
    If o["uppers"] > 0 Then
      Inc q
    Endif
    If o["lowers"] > 0 Then
      Inc q
    Endif
    If o["numbers"] > 0 Then
      Inc q
    Endif
    If o["symbols"] > 0 Then
      Inc q
    Endif
    r = r + (q * 2)
  Endif

  '' Restas
  'Solo letras
  If o["numbers"] = 0 And o["symbols"] = 0 Then
    r = r - o["chars"]
  Endif
  'Solo números
  If o["lowers"] = 0 And o["symbols"] = 0 And o["uppers"] = 0 And o["numbers"] > 0 Then
    r = r - o["numbers"]
  Endif
  'Caracteres repetidos (No sensible)
  For Each i In rep
    If i > 1 Then
      r = r - (i * (i - 1))
    Endif
  Next

  If aCUL.Count > 0 Then
    For i = 0 To aCUL.Max - 1
      If aCUL[ i ] = aCUL[ i + 1] Then
        cul[aCUL[ i ]] = cul[aCUL[ i ] ] + 1
      Endif
    Next
  Endif

  'Letras mayúsuculas consecutivas
  If cul["U"] > 0 Then
    r = r - (cul["U"] * 2)
    If cul["U"] > 3 Then
      'Sencuencia de letras (3+)
      r = r - (cul["U"] * 3)
    Endif
  Endif

  'Letras minúsculas consecutivas
  If cul["L"] > 0 Then
    r = r - (cul["L"] * 2)
    If cul["L"] > 3 Then
      'Sencuencia de letras (3+)
      r = r - (cul["L"] * 3)
    Endif
  Endif

  'Números consecutivos
  If cul["N"] > 0 Then
    r = r - (cul["N"] * 2)
    If cul["N"] > 3 Then
      'Sencuencia de números (3+)
      r = r - (cul["N"] * 3)
    Endif
  Endif

  Return r

End

Si alguien le echa un vistazo tal vez pueda ser útil.
Última modificación: 09-10-2023, 01:40 por tincho.

1 Saludo.
Grandamakulo   09-04-2024, 20:28
#8
Hola, @Tincho:
Pues que me he dicho, «Vamos a llevarle la contraria a este hombre haciendo otra función con otro criterio» y me he puesto a ello.
Que no,  Big Grin , que el motivo es otro.

Me parece que hay que tener en cuenta el número de caracteres posibles y el total de la contraseña. Evidentemente, considero que el "ataque" es bruto y no un ataque con las contraseñas más habituales.
Como el crecimiento de las posibles clave con un determinado juego de caracteres es exponencial, el cálculo se hace logarítmico. En concreto:
«Dureza» o «Fortaleza» = Log10[(Número de caracteres posibles)^(Número de caracteres de la clave)]
Está claro que (Número de caracteres posibles)^(Número de caracteres de la clave) es el número de posibles contraseñas de las mismas características, o el inverso de la probabilidad de encontrarla al primer intento.
Por ejemplo, usando el juego de caracteres de las minúsculas [a-z], cuyo cardinal es 26, la clave aaaa tendría una dureza de Log10(26^4)=5,66. La clave aaa1 la tendría de Log10(36^4)=6,22.
Adjunto la función y un pequeño ejemplo de cómo se usa y funciona.
Código:
) As Float
' ***** Calcula fortaleza de una clave
' >>>>> sClave    : Clave a examinar.
' >>>>> asGrp (*) : Grupos de caracteres que puede contener la clave.
' <<<<< Devuelve la fortaleza de la clave como Float
  
  Dim fMax As Float = +8.98846567431105E+307  ' El máximo entero, para controlar errores
  Dim fLogMax As Float = Log10(fMax)          ' Logaritmo del anterior, por lo mismo
  Dim iBase As Integer
  Dim iExponente As Integer
  Dim i, j As Integer
  
  ' Si no se incluyen grupos de caracteres, se toman los «estándard»
  If IsNull(asGrp) Then 
    asGrp.Add("abcdefghaijklmnopqrstuwxyz")
    asGrp.Add("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
    asGrp.Add("0123456789")
    asGrp.Add(" !\"#$%&\'()*+,-./:;<=>?@[\\]^_{|}~")
  Endif
  
  ' Matriz para ver qué grupos están incluidos en la clave
  Dim abGrp As New Boolean[asGrp.Count]
  
  ' El exponente es el número de caracteres de la clave
  iExponente = String.Len(sClave)
  ' Para cada grupo se ve si hay uno de sus caracteres en la clave.
  ' Si es así, se marca ese grupo.
  For i = 0 To iExponente
    For j = 0 To asGrp.Max 
      If String.InStr(asGrp[j], sClave[i]) <> 0 Then 
        abGrp[j] = Si
      Endif
    Next
  Next
  ' La base es el número de caracteres posible, esto es, la suma de los
  ' cardinales de cada conjunto de caracteres
  For i = 0 To abGrp.Max
    If abGrp[i] = Si Then iBase += asGrp[i].Len
  Next

  ' Si no se incluyen caracteres posibles, devuelve «1»
  If iBase = 0 Then Return 0
  ' Si el número obtenido es mayor que el mayor float posible, 
  ' devuelve el log10 del máximo float
  If iExponente * Log10(iBase) > fLogMax Then Return fLogMax
  ' Devuelve Log10(iBase^iExponente)
  Return iExponente * Log10(iBase)

End

En fin, a ver qué te parece.[/i][/i][/i]
Archivos adjuntos
.gz
Cuan_segura_es_una_clave_0.tar.gz (Tamaño: 33.82 KB Descargas: 3)

En un lugar de La Mancha de cuyo nombre me acuerdo perfectamente...
paskola   10-04-2024, 21:37
#9
Hola, me puse a implementar esta nueva función en mi aplicación, ya antes habia implementado la de Tincho, Y después de agregar ambas funciones, con pocos cambios, se verían como en la imagen adjunta.

Sería necesarío definir una escala de valores para darle a cada contraseña una descripción de su 'dureza'. 

Un saludo.
Archivos adjuntos
Grandamakulo   12-04-2024, 14:10
#10
Hola, @Paskola:
El problema es que usan criterios diferentes. Pero tanto en una como en otra puedes cambiar la «sensiblidad» para tener esos niveles controlados. Por ejemplo, en la de @Tincho puedes cambiar las cantidades sumadas o restadas en función de lo importante que veas cada parámetro. Con la mía, puedes cambiar el divisor del manejador de la función para obtener intervalos más cerrados o abiertos o emplear directamente el valor con tras cifras significativas.
[code]
Por cierto, en mi caso empleé estrellitas para mostrar la dureza. Las descripciones, como alguno —@Shell, por ejemplo Wink — habrá deducido son una broma hecha con frases del personaje Amador Rivas de la serie «La que se avecina» XD .

En un lugar de La Mancha de cuyo nombre me acuerdo perfectamente...
  
Usuarios navegando en este tema: 4 invitado(s)
Powered By MyBB, © 2002-2024 MyBB Group.
Made with by Curves UI.