Avatar billede coden Nybegynder
06. juli 2012 - 18:56 Der er 1 kommentar

Fejl ved generering af nøgle / brug af genereret nøgle

Hej
I forbindelse med dette indlæg: http://www.eksperten.dk/spm/965248 er jeg stødt på et problem som jeg ikke helt forstår. Alt afhængigt af hvad jeg sender med som password og salt, så fejler koden på forskellig måde. Typisk er det samme fejl som omtalt i indlægget, selvom koden tager højde for Arnes forslag. Den anden fejl der oftest kommer, er at længde af "salt ikke er på 8 bytes eller derover" Jeg er kommet frem til at det har med længden/størrelsen af password og salt at gøre, da der ved generering af "theKey" stilles nogle krav til password og salt.
Jeg har derfor forsøgt at rette op på problemet med følgende kode:

public string SetLegalLength(string inString, int minSize, int maxSize,
                            int blockSize, bool asBytes)
{
    int bitFactor = asBytes ? 8 : 1;
    string tmpString = inString;
    int tmpSize = tmpString.Length * bitFactor;
           
    if (tmpSize > maxSize)
    {
        // Extract maximum size allowed
        tmpString = tmpString.Substring(0, maxSize / bitFactor);
    }
    else if (tmpSize < maxSize)
    {
        // Set valid size
        int validSize = (tmpSize <= minSize) ? minSize :
                        (tmpSize - tmpSize % blockSize) + blockSize;
        if (tmpSize < validSize)
        {
            // Pad the key with asterisk to make up the size
            tmpString = tmpString.PadRight(validSize / bitFactor, '*');
        }
    }
    return tmpString;
}

som jeg for passwordets vedkommende kalder således:

passwordLegal = SetLegalLength(password, symAlgo.LegalKeySizes[0].MinSize,
                                        symAlgo.LegalKeySizes[0].MaxSize,
                                        symAlgo.LegalKeySizes[0].SkipSize,
                                        true);


Og for saltets vedkommende således:

saltLegal = SetLegalLength(salt, 8, 256, 1, false);

hvorefter jeg anvender passwordLegal og saltLegal fremfor password og salt når theKey skal genereres via:

Rfc2898DeriveBytes theKey = new Rfc2898DeriveBytes(passwordLegal, Encoding.ASCII.GetBytes(saltLegal), 1000);

Problemet kommer uanset om jeg sender true eller false med ind ved beregningen af saltLegal.

Jeg har på fornemmelsen at der er tale om et problem med de grænseværdier som jeg anbender ved beregningen af saltLegal. Encodingen mistænker jeg også for at spille ind på en eller anden måde.

Der er følgende forudsætninger for den løsning som jeg søger på mit problem:

1.
Password og salt kommer "udefra", dvs. i sidste ende fra noget som brugeren har indtastet, og kan derfor ikke på nogen måde hardcodes, men skal via kode gøres "lovligt" så koden kan eksekvere uden at gå ned på at password og salt ikke opfylder betingelserne.

2.
Der kan forekomme danske tegn samt specialtegn i både password og salt, hvilket skal kunne håndteres.

Geniale indspark der virker, eller kan bringe mig på sporet af en løsning er YDERST velkommen.

/Morten
Avatar billede arne_v Ekspert
06. juli 2012 - 21:02 #1
Jeg er noget skeptisk overfor SetLegalSize med bytes og laengde over 8.

Proev og kig paa output fra dette program:

using System;
using System.Security.Cryptography;

namespace E
{
    public class Program
    {
        public static string SetLegalLength(string inString, int minSize, int maxSize,
                                    int blockSize, bool asBytes)
        {
            int bitFactor = asBytes ? 8 : 1;
            string tmpString = inString;
            int tmpSize = tmpString.Length * bitFactor;
            if (tmpSize > maxSize)
            {
                // Extract maximum size allowed
                tmpString = tmpString.Substring(0, maxSize / bitFactor);
            }
            else if (tmpSize < maxSize)
            {
                // Set valid size
                int validSize = (tmpSize <= minSize) ? minSize :
                                (tmpSize - tmpSize % blockSize) + blockSize;
                if (tmpSize < validSize)
                {
                    // Pad the key with asterisk to make up the size
                    tmpString = tmpString.PadRight(validSize / bitFactor, '*');
                }
            }
            return tmpString;
        }
        private static void Assert(bool condition, string message)
        {
            if(!condition) throw new ApplicationException(message);
        }
        public static string SpecialPad(string inString, int minSize, int maxSize, int multiplaSize, bool sizeInBits)
        {
            Assert(minSize <= maxSize, "minSize must be less than or equal maxSize");
            Assert(minSize % multiplaSize == 0, "minSize must be multipla of multiplaSize");
            Assert(maxSize % multiplaSize == 0, "maxSize must be multipla of multiplaSize");
            Assert(!sizeInBits || minSize % 8 == 0, "minSize in bits must be multipla of 8");
            Assert(!sizeInBits || maxSize % 8 == 0, "maxSize in bits must be multipla of 8");
            Assert(!sizeInBits || multiplaSize % 8 == 0, "multiplaSize in bits must be multipla of 8");
            int scale = sizeInBits ? 8 : 1;
            int size = inString.Length;
            size = Math.Max(size, minSize/scale);
            size = Math.Min(size, maxSize/scale);
            size = ((size - 1) / (multiplaSize/scale) + 1) * (multiplaSize/scale);
            return inString.PadRight(maxSize/scale, '*').Substring(0, size);
        }
        public static void Main(string[] args)
        {
            for(int i = 1; i <= 16; i++)
            {
                string salt = "".PadRight(i, 'a');
                Console.WriteLine(salt);
                string saltLegal = SetLegalLength(salt, 8, 256, 1, false);
                Console.WriteLine(saltLegal);
                string saltPad = SpecialPad(salt, 8, 256, 1, false);
                Console.WriteLine(saltPad);
            }
            SymmetricAlgorithm symAlgo = new RijndaelManaged();
            for(int i = 1; i <= 16; i++)
            {
                string password = "".PadRight(i, 'b');
                Console.WriteLine(password);
                string passwordLegal = SetLegalLength(password, symAlgo.LegalKeySizes[0].MinSize,
                                        symAlgo.LegalKeySizes[0].MaxSize,
                                        symAlgo.LegalKeySizes[0].SkipSize,
                                        true);
                Console.WriteLine(passwordLegal);
                string passwordPad = SpecialPad(password, symAlgo.LegalKeySizes[0].MinSize,
                                        symAlgo.LegalKeySizes[0].MaxSize,
                                        symAlgo.LegalKeySizes[0].SkipSize,
                                        true);
                Console.WriteLine(passwordPad);
            }
            Console.ReadKey();
        }
    }
}
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester