Italian [B4J] Consiglio su password

Aldo's

Active Member
Licensed User
Buongiorno a tutti,
vorrei creare una applicazione protetta da una password.
Mi date qualche consiglio sulla memorizzazione della password (ovviamente modificabile)?
Io un paio di idee ce l'ho, ma mi piacerebbe confrontarmi con voi.
Grazie
 

sirjo66

Well-Known Member
Licensed User
Longtime User
Sistemi ce ne sono tantissimi.
Io su di un paio di miei programmi ho trasformato la password in Base64 dove però la mappa della cifratura, anzichè essere il classico "A-Z a-z 0-9 + / =", era un miscuglio e quindi indecifrabile se non avevi la mappa.
Ad esempio invece che essere "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
puoi fare "E1rSo=2dKkjqmPTsLvhWZOQguHyxt9JD+z35FAUibfIw/NeBCaX4V78pGnYRMlc06" o qualsiasi altra cosa tu voglia
Le routine di codifica/decodifica per il Base64 sono abbastanza semplici da fare se vuoi ti dò le mie scritte in VB.NET
 

Aldo's

Active Member
Licensed User
Le routine di codifica/decodifica per il Base64 sono abbastanza semplici da fare se vuoi ti dò le mie scritte in VB.NET
Se tu volessi girarmele sarei veramente contento.
Grazie
 

sirjo66

Well-Known Member
Licensed User
Longtime User
Eccole qui, poi per convertirle in B4J se hai problemi chiedi pure non preoccuparti

B4X:
    Const SJ64 = "E1rSo=2dKkjqmPTsLvhWZOQguHyxt9JD+z35FAUibfIw/NeBCaX4V78pGnYRMlc06" ' qui ovviamente puoi cambiare la mappa come vuoi tu

    Public Function SJ64enc(ByVal txt As String) As String

        Dim SJ64stop = SJ64.Substring(SJ64.Length - 1, 1)

        Dim txtb = Encoding.UTF8.GetBytes(txt)

        Dim sb As New StringBuilder

        ' divido in gruppi di 3 bytes
        For ptr = 0 To txtb.Length - 1 Step 3
            ' creo un Int32 da questi 3 byte
            Dim Vn As Int32 = &H10000 * txtb(ptr)
            If ptr + 1 < txtb.Length Then
                Vn += &H100 * txtb(ptr + 1)
            End If
            If ptr + 2 < txtb.Length Then
                Vn += txtb(ptr + 2)
            End If

            Dim Oct = Convert.ToString(Vn, 8).PadLeft(8, "0"c) ' converto in "octal"

            ' Converto in base64
            sb.Append(SJ64.Substring(Convert.ToInt32(Oct.Substring(0, 2), 8), 1))
            sb.Append(SJ64.Substring(Convert.ToInt32(Oct.Substring(2, 2), 8), 1))
            sb.Append(SJ64.Substring(Convert.ToInt32(Oct.Substring(4, 2), 8), 1))
            sb.Append(SJ64.Substring(Convert.ToInt32(Oct.Substring(6, 2), 8), 1))

        Next

        Select Case txt.Length Mod 3
            Case 1 ' 8 bit finali
                sb.Remove(sb.Length - 2, 2) '.Append(SJ64stop).Append(SJ64stop)
            Case 2 ' 16 bit finali
                sb.Remove(sb.Length - 1, 1) '.Append(SJ64stop)
        End Select
        Return sb.ToString

    End Function

    Public Function SJ64dec(ByVal txt As String) As String

        Dim SJ64stop = SJ64.Substring(SJ64.Length - 1, 1)

        ' tolgo caratteri inutili
        txt = txt.Replace(Convert.ToChar(13), "") ' vbCr
        txt = txt.Replace(Convert.ToChar(10), "") ' vbLf
        txt = txt.Replace(Convert.ToChar(9), "") ' vbTab
        txt = txt.Replace(" "c, "") ' spazi

        Do Until txt.Length Mod 4 = 0
            txt &= SJ64stop
        Loop

        Dim fp = New IO.MemoryStream

        For ptr = 0 To txt.Length - 1 Step 4
            Dim ris = "" ' risultato
            Dim numByte = 3 ' byte da convertire
            For x = 0 To 3
                Dim cc = txt.Substring(ptr + x, 1) ' estraggo carattere
                If cc = SJ64stop Then
                    numByte -= 1
                    ris &= "00"
                Else
                    ris &= Convert.ToString(SJ64.IndexOf(cc), 8).PadLeft(2, "0"c)
                End If
            Next

            Dim Vn = Convert.ToInt32(ris, 8)
            fp.WriteByte(CByte((Vn And &HFF0000) / &H10000))
            If numByte >= 2 Then fp.WriteByte(CByte((Vn And &HFF00) / &H100))
            If numByte = 3 Then fp.WriteByte(CByte(Vn And &HFF))
        Next

        Dim risb = fp.ToArray
        fp.Close()
        fp.Dispose()

        Return Encoding.UTF8.GetString(risb)

    End Function
 

LucaMs

Expert
Licensed User
Longtime User
Fai provare a ChatGPT :)

Conversione fatta da ChatGPT - quindi non è colpa mia ^__^:
' B4X version of SJ64 encoding and decoding

Dim SJ64 As String = "E1rSo=2dKkjqmPTsLvhWZOQguHyxt9JD+z35FAUibfIw/NeBCaX4V78pGnYRMlc06" ' Qui puoi cambiare la mappa come preferisci

Public Sub SJ64enc(txt As String) As String
    Dim SJ64stop As String = SJ64.SubString(SJ64.Length - 1)
    Dim txtb() As Byte = txt.GetBytes("UTF8")
    Dim sb As StringBuilder
    sb.Initialize

    For ptr = 0 To txtb.Length - 1 Step 3
        Dim Vn As Int = 256 * txtb(ptr)
        If ptr + 1 < txtb.Length Then
            Vn = Vn + 256 * txtb(ptr + 1)
        End If
        If ptr + 2 < txtb.Length Then
            Vn = Vn + txtb(ptr + 2)
        End If

        Dim Oct As String = NumberFormat(Vn, 8, 8).PadStart(8, "0"c)

        sb.Append(SJ64.SubString(NumberFormat(Oct.SubString2(0, 2), 8), 1))
        sb.Append(SJ64.SubString(NumberFormat(Oct.SubString2(2, 2), 8), 1))
        sb.Append(SJ64.SubString(NumberFormat(Oct.SubString2(4, 2), 8), 1))
        sb.Append(SJ64.SubString(NumberFormat(Oct.SubString2(6, 2), 8), 1))
    Next

    Select txt.Length Mod 3
        Case 1 ' 8 bit finali
            sb.Remove(sb.Length - 2, 2)
        Case 2 ' 16 bit finali
            sb.Remove(sb.Length - 1, 1)
    End Select

    Return sb.ToString
End Sub

Public Sub SJ64dec(txt As String) As String
    Dim SJ64stop As String = SJ64.SubString(SJ64.Length - 1)
    txt = txt.Replace(Chr(13), "").Replace(Chr(10), "").Replace(Chr(9), "").Replace(" "c, "")
    
    Do Until txt.Length Mod 4 = 0
        txt = txt & SJ64stop
    Loop

    Dim fp As OutputStream
    fp.InitializeToBytesArray(0)

    For ptr = 0 To txt.Length - 1 Step 4
        Dim ris As String = ""
        Dim numByte As Int = 3
        For x = 0 To 3
            Dim cc As String = txt.SubString2(ptr + x, ptr + x + 1)
            If cc = SJ64stop Then
                numByte = numByte - 1
                ris = ris & "00"
            Else
                ris = ris & NumberFormat(SJ64.IndexOf(cc), 8).PadStart(2, "0"c)
            End If
        Next

        Dim Vn As Int = NumberFormat(ris, 8)
        fp.WriteBytes(Array As Byte((Bit.And(Vn, &HFF0000) / &H10000), (Bit.And(Vn, &HFF00) / &H100), (Bit.And(Vn, &HFF))))
    Next

    Dim risb() As Byte = fp.ToBytesArray
    fp.Close

    Return BytesToString(risb, 0, risb.Length, "UTF8")
End Sub
 

Aldo's

Active Member
Licensed User
Fai provare a ChatGPT :)
Ecco il risultato di ChatGPT
B4X:
Sub Process_Globals
    Public App As B4JApplication
End Sub

Sub AppStart (Args() As String)
    SJ64enc("test")
    SJ64dec("dGVzdA==")
End Sub

Public Sub SJ64enc(txt As String) As String
    Dim SJ64 As String = "E1rSo=2dKkjqmPTsLvhWZOQguHyxt9JD+z35FAUibfIw/NeBCaX4V78pGnYRMlc06"
    Dim SJ64stop As String = SJ64.SubString2(SJ64.Length - 1, SJ64.Length)
    Dim txtb() As Byte = txt.GetBytes("UTF8")
    Dim sb As StringBuilder
    sb.Initialize
    For ptr = 0 To txtb.Length - 1 Step 3
        Dim Vn As Int = &H10000 * txtb(ptr)
        If ptr + 1 < txtb.Length Then
            Vn = Vn + &H100 * txtb(ptr + 1)
        End If
        If ptr + 2 < txtb.Length Then
            Vn = Vn + txtb(ptr + 2)
        End If
        Dim Oct As String = NumberFormat(Vn, 8, 0)
        sb.Append(SJ64.CharAt(NumberFormat(Oct.SubString2(0, 2), 8, 0)))
        sb.Append(SJ64.CharAt(NumberFormat(Oct.SubString2(2, 2), 8, 0)))
        sb.Append(SJ64.CharAt(NumberFormat(Oct.SubString2(4, 2), 8, 0)))
        sb.Append(SJ64.CharAt(NumberFormat(Oct.SubString2(6, 2), 8, 0)))
    Next
    Select txt.Length Mod 3
        Case 1
            sb.Remove(sb.Length - 2, 2) '.Append(SJ64stop).Append(SJ64stop)
        Case 2
            sb.Remove(sb.Length - 1, 1) '.Append(SJ64stop)
    End Select
    Return sb.ToString
End Sub

Public Sub SJ64dec(txt As String) As String
    Dim SJ64 As String = "E1rSo=2dKkjqmPTsLvhWZOQguHyxt9JD+z35FAUibfIw/NeBCaX4V78pGnYRMlc06"
    Dim SJ64stop As String = SJ64.SubString2(SJ64.Length - 1, SJ64.Length)
    txt = txt.Replace(Chr(13), "").Replace(Chr(10), "").Replace(Chr(9), "").Replace(" ", "")
    Do Until txt.Length Mod 4 = 0
        txt = txt & SJ64stop
    Loop
    Dim fp As OutputStream
    fp.InitializeToBytesArray(0)
    For ptr = 0 To txt.Length - 1 Step 4
        Dim ris As String = ""
        Dim numByte As Int = 3
        For x = 0 To 3
            Dim cc As String = txt.CharAt(x + ptr)
            If cc = SJ64stop Then
                numByte = numByte - 1
                ris = ris & "00"
            Else
                ris = ris & NumberFormat(SJ64.IndexOf(cc), 8, 0)
            End If
        Next
        Dim Vn As Int = NumberFormat(ris, 8, 0)
        fp.WriteBytes(Array As Byte((Vn And &HFF0000) / &H10000, (Vn And &HFF00) / &H100, Vn And &HFF))
    Next
    Dim risb() As Byte = fp.ToBytesArray
    fp.Close
    fp.Close
    Return BytesToString(risb, 0, risb.Length, "UTF8")
End Sub
 

Aldo's

Active Member
Licensed User
Seguendo ChatGPT mi da' un unico errore (che non so come modificarlo):
B4X:
        fp.WriteBytes(Array As Byte((Vn And &HFF0000) / &H10000, (Vn And &HFF00) / &H100, Vn And &HFF))
L'errore è:
Password - 83: Impossibile convertire il tipo: {Type=Boolean,Rank=0, RemoteObject=False} in: number.

Qualuno mi da' una mano per risolvere?
Grazie
 

sirjo66

Well-Known Member
Licensed User
Longtime User
devi fare "Vn And &HFF0000" bit a bit, per cui devi usare la libreria apposita
e ovviamente anche per gli altri byte
 

sirjo66

Well-Known Member
Licensed User
Longtime User
Scusa mi correggo, non servono librerie, dovrebbe essere:
B4X:
fp.WriteBytes(Array As Byte(Bit.And(Vn, &HFF0000) / &H10000, Bit.And(Vn, &HFF00) / &H100, Bit.And(Vn, &HFF)))

Se serve altro aiuto chiedi pure
 

Aldo's

Active Member
Licensed User
Grazie @sirjo66 e grazie a tutti.
Alla fine ho usato queste due routine semplici:
B4X:
Private Sub EncryptText(text As String, pw As String) As Byte()
    #if B4A or B4J
    Dim c As B4XCipher
    #else if B4i
    Dim c As Cipher
    #end if
    Return c.Encrypt(text.GetBytes("utf8"), pw)
End Sub

Private Sub DecryptText(EncryptedData() As Byte, pw As String) As String
    #if B4A or B4J
    Dim c As B4XCipher
    #else if B4i
    Dim c As Cipher
    #end if
    Dim b() As Byte = c.Decrypt(EncryptedData, pw)
    Return BytesToString(b, 0, b.Length, "utf8")
End Sub

con la libreria jB4XEncryption.
Buona giornata a tutti
 
Top