สร้างรหัสผ่านแบบสุ่ม


229

เมื่อผู้ใช้ในเว็บไซต์ของเราสูญเสียรหัสผ่านและออกไปที่หน้าลืมรหัสผ่านเราจำเป็นต้องให้รหัสผ่านชั่วคราวใหม่แก่เขา ฉันไม่รังเกียจที่จะสุ่มเลือกนี้หรือถ้าตรงกับกฎรหัสผ่านที่คาดเดาได้ยาก "ทั้งหมด" สิ่งที่ฉันต้องทำคือให้รหัสผ่านที่สามารถเปลี่ยนได้ในภายหลัง

แอปพลิเคชันนี้เป็นเว็บแอปพลิเคชันที่เขียนด้วย C # ดังนั้นฉันจึงคิดว่าจะเป็นคนที่ใจร้ายและไปหาเส้นทางที่ง่ายต่อการใช้ส่วนหนึ่งของ Guid กล่าวคือ

Guid.NewGuid().ToString("d").Substring(1,8)

suggesstions? ความคิด?


12
โซลูชันที่ดีบางประการที่นี่ แต่คำแนะนำเล็กน้อย: อย่าสร้างรหัสผ่านที่มีอักขระเหล่านี้: Oo0Ili (คุณเห็นสาเหตุ) :)
stian.net

2
ฉันได้เพิ่มคำตอบที่ใช้ KeePass เป็นเครื่องมือสร้างรหัสผ่านและจากตัวเลือกมากมายที่เปิดเผยฉันยังรวมตัวเลือกในการแยกอักขระที่เหมือนกันตามที่ @ stian.net พูดถึง
ปีเตอร์

คำตอบ:


570

7
ไม่ทราบว่า Framework มีวิธีการดังกล่าว! ! น่ากลัว จะสลับรหัสปัจจุบันของฉันสำหรับสิ่งนี้!
FryHard

35
ฉันพบว่าหลังจากใช้เวลาเกือบหนึ่งวันในการสร้างรหัส pw gen ของตัวเองให้สมบูรณ์ ภาพที่ฉันรู้สึก;)
Rik

16
AFAIK วิธีนี้ไม่ได้สร้างรหัสผ่านที่สอดคล้องกับนโยบายรหัสผ่านในโดเมนดังนั้นจึงไม่เหมาะสำหรับการใช้งานทุกครั้ง
teebot

19
ปัญหาหลักของวิธีนี้คือคุณไม่สามารถควบคุมชุดอักขระได้ดังนั้นคุณจึงไม่สามารถกำจัดอักขระที่ไม่ชัดเจนที่มองเห็นได้ (0oOl1i! |) ซึ่งมีความสำคัญอย่างยิ่งในทางปฏิบัติ
เดวิดแฮมมอนด์

20
มีไว้เพื่อASP.NET Coreอะไร
shashwat

114
public string CreatePassword(int length)
{
        const string valid = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
        StringBuilder res = new StringBuilder();
        Random rnd = new Random();
        while (0 < length--)
        {
            res.Append(valid[rnd.Next(valid.Length)]);
        }
        return res.ToString();
}

สิ่งนี้มีประโยชน์อย่างมากในการเลือกจากรายการอักขระที่มีอยู่สำหรับรหัสผ่านที่สร้างขึ้น (เช่นตัวเลขเท่านั้นตัวพิมพ์ใหญ่หรือตัวพิมพ์เล็กเท่านั้นเป็นต้น)


2
วิธีนี้ (ฐาน 62) ดีกว่า GUID (ฐาน 16) ต่อความแข็งแรง: สตริงเลขฐานสิบหก 8 ตัวเทียบเท่ากับตัวอักษรผสมตัวเลข 4-5 ตัว
Jimmy

57
Randomไม่ปลอดภัยแบบเข้ารหัส System.Security.Cryptography.RNGCryptoServiceProviderเป็นทางเลือกที่ดีกว่า
Anaximander

3
สิ่งนี้จะสร้างรหัสผ่านเดียวกันทุกครั้งที่มีการเรียกใช้เมธอดเนื่องจากคลาส Random จะถูกสร้างอินสแตนซ์ในแต่ละครั้ง สิ่งนี้สามารถทำให้ปลอดภัยได้โดยการย้าย Random ออกจากวิธีนี้และนำอินสแตนซ์กลับมาใช้ใหม่
Jon

6
ไม่มันจะไม่ นอกจากคนสองคนตัดสินใจเปลี่ยนรหัสผ่านในเวลานาฬิกาเดียวกัน
Radu094

10
อ้างจากคำถาม: ไม่สนใจ "ถ้ามันตรงกับ" จำเป็น "กฎรหัสผ่านที่คาดเดายากทั้งหมด" ... ขอบคุณสำหรับ downvoting คำตอบนี้แม้ว่า
Radu094

35

เป้าหมายหลักของรหัสของฉันคือ:

  1. การแจกแจงของสตริงนั้นเกือบจะเหมือนกัน (ไม่ต้องสนใจค่าเบี่ยงเบนเล็ก ๆ น้อย ๆ ตราบใดที่มันเล็ก)
  2. มันส่งออกมากกว่าสองสามพันล้านสายสำหรับแต่ละชุดอาร์กิวเมนต์ การสร้างสตริงอักขระ 8 ตัว (~ 47 บิตของเอนโทรปี) นั้นไม่มีความหมายหาก PRNG ของคุณสร้างค่าต่างกันเพียง 2 พันล้าน (31 บิตของเอนโทรปี)
  3. มีความปลอดภัยเนื่องจากฉันคาดว่าผู้คนจะใช้รหัสผ่านนี้หรือโทเค็นความปลอดภัยอื่น ๆ

คุณสมบัติแรกสามารถทำได้โดยการใช้โมดูโลขนาด 64 บิต สำหรับตัวอักษรขนาดเล็ก (เช่นตัวอักษร 62 ตัวจากคำถาม) สิ่งนี้นำไปสู่การมีอคติเล็กน้อย ที่สองและสามคุณสมบัติที่จะประสบความสำเร็จโดยใช้แทนRNGCryptoServiceProviderSystem.Random

using System;
using System.Security.Cryptography;

public static string GetRandomAlphanumericString(int length)
{
    const string alphanumericCharacters =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
        "abcdefghijklmnopqrstuvwxyz" +
        "0123456789";
    return GetRandomString(length, alphanumericCharacters);
}

public static string GetRandomString(int length, IEnumerable<char> characterSet)
{
    if (length < 0)
        throw new ArgumentException("length must not be negative", "length");
    if (length > int.MaxValue / 8) // 250 million chars ought to be enough for anybody
        throw new ArgumentException("length is too big", "length");
    if (characterSet == null)
        throw new ArgumentNullException("characterSet");
    var characterArray = characterSet.Distinct().ToArray();
    if (characterArray.Length == 0)
        throw new ArgumentException("characterSet must not be empty", "characterSet");

    var bytes = new byte[length * 8];
    new RNGCryptoServiceProvider().GetBytes(bytes);
    var result = new char[length];
    for (int i = 0; i < length; i++)
    {
        ulong value = BitConverter.ToUInt64(bytes, i * 8);
        result[i] = characterArray[value % (uint)characterArray.Length];
    }
    return new string(result);
}

(นี่คือสำเนาของคำตอบของฉันฉันจะสร้างอักขระ 8 ตัวแบบสุ่มสตริงตัวอักษรและตัวเลขใน C # ได้อย่างไร )


1
ถ้า UInt64.MaxValue ไม่สามารถแบ่งได้อย่างทั่วถึงโดย characterArray.Length อักขระที่เลือกแบบสุ่มจะไม่ถูกกระจายอย่างเท่าเทียมกัน (แม้ว่านี่จะเป็นเอฟเฟกต์เล็ก ๆ )
Jeff Walker Code Ranger

1
@JeffWalkerCodeRanger นั่นเป็นเหตุผลที่ฉันพูดว่ามีอคติเล็กน้อยไม่ใช่ไม่มีอคติ แม้จะมี Petabyte ของเอาต์พุตคุณยังมีน้อยกว่า 1% ในการแยกความแตกต่างนี้จากตัวสร้างสตริงที่ไม่มีอคติอย่างสมบูรณ์ ความซับซ้อนเพิ่มเติมของการไม่เอนเอียงที่สมบูรณ์แบบนั้นเห็นได้ชัดว่าไม่คุ้มกับผลกำไรทางทฤษฎีในการสุ่มที่นี่
CodesInChaos

9
สำหรับผู้ที่ใช้. NET Core ให้แทนที่ "ใหม่ RNGCryptoServiceProvider (). GetBytes (ไบต์);" ด้วย "System.Security.Cryptography.RandomNumberGenerator.Create (). GetBytes (ไบต์);"
NPNelson

24
public string GenerateToken(int length)
{
    using (RNGCryptoServiceProvider cryptRNG = new RNGCryptoServiceProvider())
    {
        byte[] tokenBuffer = new byte[length];
        cryptRNG.GetBytes(tokenBuffer);
        return Convert.ToBase64String(tokenBuffer);
    }
}

(คุณอาจมีคลาสที่วิธีนี้ใช้งาน IDisposable ถือการอ้างอิงRNGCryptoServiceProviderและกำจัดอย่างถูกต้องเพื่อหลีกเลี่ยงการทำให้อินสแตนซ์มันซ้ำ ๆ )

มีการบันทึกไว้ว่าเนื่องจากจะส่งคืนสตริง -64 เบสความยาวเอาต์พุตจะเป็นผลคูณของ 4 เสมอโดยมีพื้นที่พิเศษที่ใช้=เป็นอักขระการขยาย lengthพารามิเตอร์ระบุความยาวของบัฟเฟอร์ไบต์ไม่สตริงเอาท์พุท (และดังนั้นจึงอาจจะไม่ได้เป็นชื่อที่ดีที่สุดสำหรับพารามิเตอร์ที่ตอนนี้ฉันคิดเกี่ยวกับมัน) สิ่งนี้จะควบคุมว่าจะมีรหัสผ่านจำนวนกี่ไบต์ของเอนโทรปี อย่างไรก็ตามเนื่องจากฐาน 64 ใช้บล็อก 4 ตัวเพื่อเข้ารหัสแต่ละอินพุต 3 ไบต์หากคุณขอความยาวที่ไม่ใช่หลายตัว 3 จะมี "ช่องว่าง" เพิ่มเติมและจะใช้=เพื่อเติม พิเศษ

หากคุณไม่ชอบการใช้สตริงเบส -64 ไม่ว่าด้วยเหตุผลใดคุณสามารถแทนที่การConvert.ToBase64String()โทรด้วยการแปลงเป็นสตริงปกติหรือใช้Encodingวิธีใดก็ได้ เช่น. Encoding.UTF8.GetString(tokenBuffer)- ตรวจสอบให้แน่ใจว่าคุณเลือกชุดอักขระที่สามารถแสดงค่าทั้งหมดที่ออกมาจาก RNG และสร้างอักขระที่เข้ากันได้กับทุกที่ที่คุณส่งหรือเก็บสิ่งนี้ ตัวอย่างเช่นการใช้ Unicode มีแนวโน้มที่จะให้ตัวอักษรจีนจำนวนมาก การใช้ base-64 รับประกันชุดอักขระที่เข้ากันได้อย่างกว้างขวางและลักษณะของสตริงดังกล่าวไม่ควรทำให้มีความปลอดภัยน้อยลงหากคุณใช้อัลกอริทึมการแฮชที่เหมาะสม


ฉันคิดว่าคุณตั้งใจจะใส่ tokenBuffer ในตำแหน่งที่คุณมี linkBuf
PIntag

เมื่อฉันใช้รหัสนี้และส่งผ่านความยาว 10 สตริงที่ส่งคืนจะมีความยาว 16 อักขระเสมอและอักขระสุดท้าย 2 ตัวจะเป็น "==" เสมอ ฉันใช้มันไม่ถูกต้องหรือไม่? มีการระบุความยาวเป็น hex หรือไม่?
PIntag

1
ความยาวที่ระบุคือจำนวนไบต์ของการสุ่ม (หรือ "เอนโทรปี" ตามที่รู้จักกันในทางเทคนิค) อย่างไรก็ตามค่าที่ส่งคืนคือการเข้ารหัส base-64 ซึ่งหมายความว่าเนื่องจากการเข้ารหัส base-64 ทำงานได้อย่างไรความยาวของเอาต์พุตจึงเป็นผลคูณของ 4 เสมอในบางครั้งนั่นเป็นอักขระที่มากกว่าที่จะต้องเข้ารหัสอักขระทั้งหมดดังนั้นจึงใช้ = ตัวอักษรเพื่อวางส่วนที่เหลือออก
anaximander

1
RNGCryptoServiceProvider เป็น IDisposable ดังนั้นฉันจะใช้มันด้วยรูปแบบการใช้ (เช่นการใช้ (var cryptRNG = ใหม่ RNGCryptoServiceProvider ()) {... })
kloarubeek

@ kloarubeek จุดที่ถูกต้องและข้อเสนอแนะที่ดี ฉันได้เพิ่มเข้าไปในตัวอย่างรหัสของฉัน
anaximander

20

มันใหญ่กว่านี้เยอะ แต่ฉันคิดว่ามันดูครอบคลุมกว่าเล็กน้อย: http://www.obviex.com/Samples/Password.aspx

///////////////////////////////////////////////////////////////////////////////
// SAMPLE: Generates random password, which complies with the strong password
//         rules and does not contain ambiguous characters.
//
// To run this sample, create a new Visual C# project using the Console
// Application template and replace the contents of the Class1.cs file with
// the code below.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// 
// Copyright (C) 2004 Obviex(TM). All rights reserved.
// 
using System;
using System.Security.Cryptography;

/// <summary>
/// This class can generate random passwords, which do not include ambiguous 
/// characters, such as I, l, and 1. The generated password will be made of
/// 7-bit ASCII symbols. Every four characters will include one lower case
/// character, one upper case character, one number, and one special symbol
/// (such as '%') in a random order. The password will always start with an
/// alpha-numeric character; it will not start with a special symbol (we do
/// this because some back-end systems do not like certain special
/// characters in the first position).
/// </summary>
public class RandomPassword
{
    // Define default min and max password lengths.
    private static int DEFAULT_MIN_PASSWORD_LENGTH  = 8;
    private static int DEFAULT_MAX_PASSWORD_LENGTH  = 10;

    // Define supported password characters divided into groups.
    // You can add (or remove) characters to (from) these groups.
    private static string PASSWORD_CHARS_LCASE  = "abcdefgijkmnopqrstwxyz";
    private static string PASSWORD_CHARS_UCASE  = "ABCDEFGHJKLMNPQRSTWXYZ";
    private static string PASSWORD_CHARS_NUMERIC= "23456789";
    private static string PASSWORD_CHARS_SPECIAL= "*$-+?_&=!%{}/";

    /// <summary>
    /// Generates a random password.
    /// </summary>
    /// <returns>
    /// Randomly generated password.
    /// </returns>
    /// <remarks>
    /// The length of the generated password will be determined at
    /// random. It will be no shorter than the minimum default and
    /// no longer than maximum default.
    /// </remarks>
    public static string Generate()
    {
        return Generate(DEFAULT_MIN_PASSWORD_LENGTH, 
                        DEFAULT_MAX_PASSWORD_LENGTH);
    }

    /// <summary>
    /// Generates a random password of the exact length.
    /// </summary>
    /// <param name="length">
    /// Exact password length.
    /// </param>
    /// <returns>
    /// Randomly generated password.
    /// </returns>
    public static string Generate(int length)
    {
        return Generate(length, length);
    }

    /// <summary>
    /// Generates a random password.
    /// </summary>
    /// <param name="minLength">
    /// Minimum password length.
    /// </param>
    /// <param name="maxLength">
    /// Maximum password length.
    /// </param>
    /// <returns>
    /// Randomly generated password.
    /// </returns>
    /// <remarks>
    /// The length of the generated password will be determined at
    /// random and it will fall with the range determined by the
    /// function parameters.
    /// </remarks>
    public static string Generate(int   minLength,
                                  int   maxLength)
    {
        // Make sure that input parameters are valid.
        if (minLength <= 0 || maxLength <= 0 || minLength > maxLength)
            return null;

        // Create a local array containing supported password characters
        // grouped by types. You can remove character groups from this
        // array, but doing so will weaken the password strength.
        char[][] charGroups = new char[][] 
        {
            PASSWORD_CHARS_LCASE.ToCharArray(),
            PASSWORD_CHARS_UCASE.ToCharArray(),
            PASSWORD_CHARS_NUMERIC.ToCharArray(),
            PASSWORD_CHARS_SPECIAL.ToCharArray()
        };

        // Use this array to track the number of unused characters in each
        // character group.
        int[] charsLeftInGroup = new int[charGroups.Length];

        // Initially, all characters in each group are not used.
        for (int i=0; i<charsLeftInGroup.Length; i++)
            charsLeftInGroup[i] = charGroups[i].Length;

        // Use this array to track (iterate through) unused character groups.
        int[] leftGroupsOrder = new int[charGroups.Length];

        // Initially, all character groups are not used.
        for (int i=0; i<leftGroupsOrder.Length; i++)
            leftGroupsOrder[i] = i;

        // Because we cannot use the default randomizer, which is based on the
        // current time (it will produce the same "random" number within a
        // second), we will use a random number generator to seed the
        // randomizer.

        // Use a 4-byte array to fill it with random bytes and convert it then
        // to an integer value.
        byte[] randomBytes = new byte[4];

        // Generate 4 random bytes.
        RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
        rng.GetBytes(randomBytes);

        // Convert 4 bytes into a 32-bit integer value.
        int seed = BitConverter.ToInt32(randomBytes, 0);

        // Now, this is real randomization.
        Random  random  = new Random(seed);

        // This array will hold password characters.
        char[] password = null;

        // Allocate appropriate memory for the password.
        if (minLength < maxLength)
            password = new char[random.Next(minLength, maxLength+1)];
        else
            password = new char[minLength];

        // Index of the next character to be added to password.
        int nextCharIdx;

        // Index of the next character group to be processed.
        int nextGroupIdx;

        // Index which will be used to track not processed character groups.
        int nextLeftGroupsOrderIdx;

        // Index of the last non-processed character in a group.
        int lastCharIdx;

        // Index of the last non-processed group.
        int lastLeftGroupsOrderIdx = leftGroupsOrder.Length - 1;

        // Generate password characters one at a time.
        for (int i=0; i<password.Length; i++)
        {
            // If only one character group remained unprocessed, process it;
            // otherwise, pick a random character group from the unprocessed
            // group list. To allow a special character to appear in the
            // first position, increment the second parameter of the Next
            // function call by one, i.e. lastLeftGroupsOrderIdx + 1.
            if (lastLeftGroupsOrderIdx == 0)
                nextLeftGroupsOrderIdx = 0;
            else
                nextLeftGroupsOrderIdx = random.Next(0, 
                                                     lastLeftGroupsOrderIdx);

            // Get the actual index of the character group, from which we will
            // pick the next character.
            nextGroupIdx = leftGroupsOrder[nextLeftGroupsOrderIdx];

            // Get the index of the last unprocessed characters in this group.
            lastCharIdx = charsLeftInGroup[nextGroupIdx] - 1;

            // If only one unprocessed character is left, pick it; otherwise,
            // get a random character from the unused character list.
            if (lastCharIdx == 0)
                nextCharIdx = 0;
            else
                nextCharIdx = random.Next(0, lastCharIdx+1);

            // Add this character to the password.
            password[i] = charGroups[nextGroupIdx][nextCharIdx];

            // If we processed the last character in this group, start over.
            if (lastCharIdx == 0)
                charsLeftInGroup[nextGroupIdx] = 
                                          charGroups[nextGroupIdx].Length;
            // There are more unprocessed characters left.
            else
            {
                // Swap processed character with the last unprocessed character
                // so that we don't pick it until we process all characters in
                // this group.
                if (lastCharIdx != nextCharIdx)
                {
                    char temp = charGroups[nextGroupIdx][lastCharIdx];
                    charGroups[nextGroupIdx][lastCharIdx] = 
                                charGroups[nextGroupIdx][nextCharIdx];
                    charGroups[nextGroupIdx][nextCharIdx] = temp;
                }
                // Decrement the number of unprocessed characters in
                // this group.
                charsLeftInGroup[nextGroupIdx]--;
            }

            // If we processed the last group, start all over.
            if (lastLeftGroupsOrderIdx == 0)
                lastLeftGroupsOrderIdx = leftGroupsOrder.Length - 1;
            // There are more unprocessed groups left.
            else
            {
                // Swap processed group with the last unprocessed group
                // so that we don't pick it until we process all groups.
                if (lastLeftGroupsOrderIdx != nextLeftGroupsOrderIdx)
                {
                    int temp = leftGroupsOrder[lastLeftGroupsOrderIdx];
                    leftGroupsOrder[lastLeftGroupsOrderIdx] = 
                                leftGroupsOrder[nextLeftGroupsOrderIdx];
                    leftGroupsOrder[nextLeftGroupsOrderIdx] = temp;
                }
                // Decrement the number of unprocessed groups.
                lastLeftGroupsOrderIdx--;
            }
        }

        // Convert password characters into a string and return the result.
        return new string(password);
     }
}

/// <summary>
/// Illustrates the use of the RandomPassword class.
/// </summary>
public class RandomPasswordTest
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main(string[] args)
    {
        // Print 100 randomly generated passwords (8-to-10 char long).
        for (int i=0; i<100; i++)
            Console.WriteLine(RandomPassword.Generate(8, 10));
    }
}
//
// END OF FILE
///////////////////////////////////////////////////////////////////////////////

2
ปรากฎว่ามีการสนับสนุนนี้โดยกรอบ ดังนั้นฉันจึงยอมรับคำตอบนั้นแทน!
FryHard

1
การสร้างรหัสผ่านที่แตกต่างกันเพียง 2 ^ 31 ถึงแม้จะมีขนาดเอาต์พุตที่ยาว แต่ก็เป็นบิตที่ด้านล่าง อาจเพียงพอต่อการโจมตีออนไลน์ แต่แน่นอนว่าเล็กไปสำหรับการโจมตีออฟไลน์ => ฉันจะไม่แนะนำสิ่งนี้
CodesInChaos

นี่ยังเป็นคำตอบที่ดีเพราะการสนับสนุน "ในตัว" เป็นสมาชิกจริง ๆ แล้วถ้าคุณตัดสินใจที่จะไม่ใช้สมาชิก ASP.NET ล่ะ? มันยังใช้งานได้เนื่องจากการพึ่งพาเป็น System.Web.dll แต่มันก็น่าอึดอัดใจเล็กน้อยเพราะวิธีการไม่ได้อยู่ในตัวเอง @GEOCHET: ขอบคุณที่โพสต์ทางเลือกนี้
Chris Gomez

8

ฉันรู้ว่านี่เป็นเธรดเก่า แต่ฉันมีสิ่งที่อาจเป็นวิธีที่ค่อนข้างง่ายสำหรับคนที่จะใช้ ใช้งานง่ายเข้าใจง่ายและตรวจสอบได้ง่าย

พิจารณาข้อกำหนดต่อไปนี้:

ฉันต้องการรหัสผ่านแบบสุ่มในการสร้างซึ่งมีตัวอักษรตัวพิมพ์เล็กอย่างน้อย 2 ตัวตัวอักษรตัวพิมพ์ใหญ่ 2 ตัวและตัวเลข 2 ตัว รหัสผ่านจะต้องมีความยาวอย่างน้อย 8 ตัวอักษร

นิพจน์ทั่วไปต่อไปนี้สามารถตรวจสอบกรณีนี้:

^(?=\b\w*[a-z].*[a-z]\w*\b)(?=\b\w*[A-Z].*[A-Z]\w*\b)(?=\b\w*[0-9].*[0-9]\w*\b)[a-zA-Z0-9]{8,}$

มันอยู่นอกขอบเขตของคำถามนี้ - แต่ regex เป็นไปตาม lookahead / lookbehindและLookAround

รหัสต่อไปนี้จะสร้างชุดอักขระแบบสุ่มซึ่งตรงกับข้อกำหนดนี้:

public static string GeneratePassword(int lowercase, int uppercase, int numerics) {
    string lowers = "abcdefghijklmnopqrstuvwxyz";
    string uppers = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    string number = "0123456789";

    Random random = new Random();

    string generated = "!";
    for (int i = 1; i <= lowercase; i++)
        generated = generated.Insert(
            random.Next(generated.Length), 
            lowers[random.Next(lowers.Length - 1)].ToString()
        );

    for (int i = 1; i <= uppercase; i++)
        generated = generated.Insert(
            random.Next(generated.Length), 
            uppers[random.Next(uppers.Length - 1)].ToString()
        );

    for (int i = 1; i <= numerics; i++)
        generated = generated.Insert(
            random.Next(generated.Length), 
            number[random.Next(number.Length - 1)].ToString()
        );

    return generated.Replace("!", string.Empty);

}

เพื่อให้ตรงกับความต้องการข้างต้นเพียงโทรไปที่:

String randomPassword = GeneratePassword(3, 3, 3);

รหัสเริ่มต้นด้วยอักขระที่ไม่ถูกต้อง ( "!") - เพื่อให้สตริงมีความยาวที่สามารถฉีดอักขระใหม่ได้

จากนั้นจะวนจาก 1 ไปยัง # ของอักขระตัวพิมพ์เล็กที่ต้องการและในแต่ละการวนซ้ำจะจับรายการสุ่มจากรายการตัวพิมพ์เล็กและแทรกลงในตำแหน่งสุ่มในสตริง

จากนั้นจะวนซ้ำตัวอักษรตัวพิมพ์ใหญ่และตัวเลข

สิ่งนี้จะช่วยให้คุณย้อนกลับสตริงที่มีความยาว = lowercase + uppercase + numericsซึ่งเป็นตัวพิมพ์เล็กตัวพิมพ์ใหญ่และตัวอักษรตัวเลขของการนับที่คุณต้องการถูกวางในลำดับแบบสุ่ม


3
อย่าใช้System.Randomสำหรับสิ่งสำคัญด้านความปลอดภัยเช่นรหัสผ่าน ใช้RNGCryptoServiceProvider
CodesInChaos

lowers[random.Next(lowers.Length - 1)].ToString() รหัสนี้จะไม่สร้าง 'z' Random.Next จะสร้างจำนวนเต็มน้อยกว่าจำนวนที่ให้ไว้ดังนั้นคุณไม่ควรลบเลขพิเศษนั้นจากความยาว
notbono

6

สำหรับรหัสผ่านประเภทนี้ฉันมักจะใช้ระบบที่น่าจะสร้างรหัสผ่าน "ใช้แล้ว" ได้ง่ายขึ้น สั้นมักประกอบด้วยเศษเล็กเศษน้อยที่ออกเสียงได้และมีตัวเลขน้อยและไม่มีความกำกวมระหว่างเครื่องหมาย (นั่นคือ 0 หรือ O? A 1 หรือ I?) สิ่งที่ต้องการ

string[] words = { 'bur', 'ler', 'meh', 'ree' };
string word = "";

Random rnd = new Random();
for (i = 0; i < 3; i++)
   word += words[rnd.Next(words.length)]

int numbCount = rnd.Next(4);
for (i = 0; i < numbCount; i++)
  word += (2 + rnd.Next(7)).ToString();

return word;

(พิมพ์ลงในเบราว์เซอร์เพื่อใช้เป็นแนวทางเท่านั้นและเพิ่มคำเพิ่มเติม)


6

ฉันไม่ชอบรหัสผ่านที่ Membership.GeneratePassword () สร้างขึ้นเพราะมันน่าเกลียดเกินไปและมีอักขระพิเศษมากเกินไป

รหัสนี้สร้างรหัสผ่าน 10 หลักที่ไม่น่าเกลียด

string password = Guid.NewGuid().ToString("N").ToLower()
                      .Replace("1", "").Replace("o", "").Replace("0","")
                      .Substring(0,10);

แน่นอนว่าฉันสามารถใช้ Regex เพื่อทำหน้าที่แทนทั้งหมด แต่นี่เป็น IMO ที่สามารถอ่านและบำรุงรักษาได้มากกว่า


2
ไม่ควรใช้ GUID เป็น crypto PRNG
CodesInChaos

3
หากคุณกำลังจะใช้วิธีนี้คุณสามารถใช้. ToString ("N") และคุณไม่จำเป็นต้องแทนที่ "-" นอกจากนี้ยังไม่จำเป็นต้องแทนที่ "l" เนื่องจากไม่ใช่เลขฐานสิบหก
JackAce

เห็นอย่างสมบูรณ์ว่าทำไมคุณถึงทำเช่นนี้ ฉันเพิ่งต้องการรหัสผ่านสั้น ๆ (น้อยกว่าหนึ่งวัน) ที่ไม่จำเป็นต้องมีความซ้ำซ้อนต่อผู้ใช้ การดึงสิ่งที่ออกมาและเลขศูนย์เป็นวิธีที่ยอดเยี่ยมในการทำให้สับสน ฉันแค่เปลี่ยนของฉันเป็นตัวพิมพ์ใหญ่แล้วตัดความยาวเป็น 6 เช่นเดียวกับข้อเสนอแนะ 'N' เช่นกัน ขอบคุณ!
Bill Noel

6

ฉันสร้างคลาสนี้ที่ใช้ RNGCryptoServiceProvider และยืดหยุ่นได้ ตัวอย่าง:

var generator = new PasswordGenerator(minimumLengthPassword: 8,
                                      maximumLengthPassword: 15,
                                      minimumUpperCaseChars: 2,
                                      minimumNumericChars: 3,
                                      minimumSpecialChars: 2);
string password = generator.Generate();

นั่นเป็นสิ่งที่ดีใบอนุญาตในชั้นเรียนนั้นคืออะไร? ฉันสามารถใช้มันได้หรือไม่
codeulike

ใช้มันเหมือนที่คุณต้องการ!
Alex Siepman

3

ฉันสร้างวิธีนี้คล้ายกับที่มีอยู่ในผู้ให้บริการสมาชิก สิ่งนี้มีประโยชน์หากคุณไม่ต้องการเพิ่มการอ้างอิงเว็บในบางแอปพลิเคชัน

มันใช้งานได้ดี

public static string GeneratePassword(int Length, int NonAlphaNumericChars)
    {
        string allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789";
        string allowedNonAlphaNum = "!@#$%^&*()_-+=[{]};:<>|./?";
        Random rd = new Random();

        if (NonAlphaNumericChars > Length || Length <= 0 || NonAlphaNumericChars < 0)
            throw new ArgumentOutOfRangeException();

            char[] pass = new char[Length];
            int[] pos = new int[Length];
            int i = 0, j = 0, temp = 0;
            bool flag = false;

            //Random the position values of the pos array for the string Pass
            while (i < Length - 1)
            {
                j = 0;
                flag = false;
                temp = rd.Next(0, Length);
                for (j = 0; j < Length; j++)
                    if (temp == pos[j])
                    {
                        flag = true;
                        j = Length;
                    }

                if (!flag)
                {
                    pos[i] = temp;
                    i++;
                }
            }

            //Random the AlphaNumericChars
            for (i = 0; i < Length - NonAlphaNumericChars; i++)
                pass[i] = allowedChars[rd.Next(0, allowedChars.Length)];

            //Random the NonAlphaNumericChars
            for (i = Length - NonAlphaNumericChars; i < Length; i++)
                pass[i] = allowedNonAlphaNum[rd.Next(0, allowedNonAlphaNum.Length)];

            //Set the sorted array values by the pos array for the rigth posistion
            char[] sorted = new char[Length];
            for (i = 0; i < Length; i++)
                sorted[i] = pass[pos[i]];

            string Pass = new String(sorted);

            return Pass;
    }

6
อย่าใช้System.Randomสำหรับสิ่งสำคัญด้านความปลอดภัยเช่นรหัสผ่าน ใช้RNGCryptoServiceProvider
CodesInChaos

3

ฉันมีความสุขมากกับตัวสร้างรหัสผ่านในตัว KeePass เนื่องจาก KeePass เป็นโปรแกรม. Net และโอเพ่นซอร์สฉันจึงตัดสินใจที่จะขุดไปรอบ ๆ โค้ดเล็กน้อย ฉันลงเอยด้วยการอ้างอิง KeePass.exe สำเนาที่ให้ไว้ในการติดตั้งแอปพลิเคชันมาตรฐานเป็นการอ้างอิงในโครงการของฉันและเขียนรหัสด้านล่าง คุณสามารถดูว่ามันมีความยืดหยุ่นได้อย่างไรด้วย KeePass คุณสามารถระบุความยาวอักขระที่จะรวม / ไม่รวม ฯลฯ ...

using KeePassLib.Cryptography.PasswordGenerator;
using KeePassLib.Security;


public static string GeneratePassword(int passwordLength, bool lowerCase, bool upperCase, bool digits,
        bool punctuation, bool brackets, bool specialAscii, bool excludeLookAlike)
    {
        var ps = new ProtectedString();
        var profile = new PwProfile();
        profile.CharSet = new PwCharSet();
        profile.CharSet.Clear();

        if (lowerCase)
            profile.CharSet.AddCharSet('l');
        if(upperCase)
            profile.CharSet.AddCharSet('u');
        if(digits)
            profile.CharSet.AddCharSet('d');
        if (punctuation)
            profile.CharSet.AddCharSet('p');
        if (brackets)
            profile.CharSet.AddCharSet('b');
        if (specialAscii)
            profile.CharSet.AddCharSet('s');

        profile.ExcludeLookAlike = excludeLookAlike;
        profile.Length = (uint)passwordLength;
        profile.NoRepeatingCharacters = true;

        KeePassLib.Cryptography.PasswordGenerator.PwGenerator.Generate(out ps, profile, null, _pool);

        return ps.ReadString();
    }

2
public static string GeneratePassword(int passLength) {
        var chars = "abcdefghijklmnopqrstuvwxyz@#$&ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        var random = new Random();
        var result = new string(
            Enumerable.Repeat(chars, passLength)
                      .Select(s => s[random.Next(s.Length)])
                      .ToArray());
        return result;
    }

โปรดอธิบายคำตอบของคุณ
Linus

1
ฟังก์ชั่นนี้ใช้งานได้ดีมากกับการเปลี่ยนแปลงเล็กน้อย 1. เพิ่มเอนโทรปีหากคุณทำการโทรหลายครั้งพร้อมกัน ซึ่งหมายความว่าเรียกว่า Sleep () หรือเอนโทรปีอื่น ๆ ที่ก่อให้เกิดฟังก์ชันระหว่างการโทร 2. เพิ่มจำนวนและการสุ่มของอักขระต้นฉบับ ฉันสร้างชุดรหัสผ่าน 500 อักขระด้วยรหัสผ่านแบบไม่รวมจำนวนอักขระที่คล้ายกันและอักขระที่หลีกเลี่ยงได้อื่น ๆ ที่ฉันไม่ต้องการจัดการและใช้สตริงอักขระ 2000 ผลลัพธ์ การสุ่มหลังจากแม้แต่ 100ms ของเอนโทรปีก็ค่อนข้างดี
Wizengamot

2

ฉันจะเพิ่มคำตอบที่ไม่เหมาะสมไปยังหม้อ

ฉันมีกรณีการใช้งานที่ฉันต้องการรหัสผ่านแบบสุ่มสำหรับการสื่อสารของเครื่องจักร - เครื่องดังนั้นฉันจึงไม่มีข้อกำหนดใด ๆ สำหรับการอ่านของมนุษย์ ฉันยังไม่มีสิทธิ์เข้าถึงMembership.GeneratePasswordในโครงการของฉันและไม่ต้องการเพิ่มการพึ่งพา

ฉันค่อนข้างแน่ใจว่าMembership.GeneratePasswordกำลังทำอะไรบางอย่างที่คล้ายกับสิ่งนี้ แต่ที่นี่คุณสามารถปรับแต่งกลุ่มของตัวละครที่จะดึงออกมาได้

public static class PasswordGenerator
{
    private readonly static Random _rand = new Random();

    public static string Generate(int length = 24)
    {
        const string lower = "abcdefghijklmnopqrstuvwxyz";
        const string upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        const string number = "1234567890";
        const string special = "!@#$%^&*_-=+";

        // Get cryptographically random sequence of bytes
        var bytes = new byte[length];
        new RNGCryptoServiceProvider().GetBytes(bytes);

        // Build up a string using random bytes and character classes
        var res = new StringBuilder();
        foreach(byte b in bytes)
        {
            // Randomly select a character class for each byte
            switch (_rand.Next(4))
            {
                // In each case use mod to project byte b to the correct range
                case 0:
                    res.Append(lower[b % lower.Count()]);
                    break;
                case 1:
                    res.Append(upper[b % upper.Count()]);
                    break;
                case 2:
                    res.Append(number[b % number.Count()]);
                    break;
                case 3:
                    res.Append(special[b % special.Count()]);
                    break;
            }
        }
        return res.ToString();
    }
}

และตัวอย่างบางส่วนของผลลัพธ์:

PasswordGenerator.Generate(12)
"pzY=64@-ChS$"
"BG0OsyLbYnI_"
"l9#5^2&adj_i"
"#++Ws9d$%O%X"
"IWhdIN-#&O^s"

หากต้องการข้อร้องเรียนเกี่ยวกับการใช้Random: แหล่งที่มาหลักของการสุ่มยังคงเป็น crypto RNG แม้ว่าคุณจะสามารถกำหนดลำดับออกมาล่วงหน้าRandom(พูดว่ามันผลิตเท่านั้น1) คุณยังไม่ทราบว่าตัวละครตัวต่อไปที่จะถูกเลือก (แม้ว่ามันจะจำกัด ช่วงของความเป็นไปได้)

ส่วนขยายที่เรียบง่ายอย่างหนึ่งคือการเพิ่มน้ำหนักให้กับชุดอักขระที่แตกต่างกันซึ่งอาจทำได้ง่ายเพียงแค่เพิ่มค่าสูงสุดและเพิ่มเคสที่ลดลงเพื่อเพิ่มน้ำหนัก

switch (_rand.Next(6))
{
    // Prefer letters 2:1
    case 0:
    case 1:
        res.Append(lower[b % lower.Count()]);
        break;
    case 2:
    case 3:
        res.Append(upper[b % upper.Count()]);
        break;
    case 4:
        res.Append(number[b % number.Count()]);
        break;
    case 5:
        res.Append(special[b % special.Count()]);
        break;
}

สำหรับกำเนิดไฟฟ้ารหัสผ่านเห็นอกเห็นใจมากขึ้นแบบสุ่มผมเคยใช้ระบบพรอมต์ใช้รายการเอฟเอฟลูกเต๋าคำ


1

ฉันชอบดูการสร้างรหัสผ่านเช่นเดียวกับการสร้างคีย์ซอฟต์แวร์ คุณควรเลือกตัวละครที่มีแนวปฏิบัติที่ดี ตอบสิ่งที่@ Radu094และแก้ไขเพื่อให้เป็นไปตามแนวปฏิบัติที่ดี อย่าใส่ตัวอักษรทุกตัวลงในอาร์เรย์อักขระ ตัวอักษรบางตัวยากที่จะพูดหรือเข้าใจทางโทรศัพท์

คุณควรพิจารณาการใช้การตรวจสอบกับรหัสผ่านที่สร้างขึ้นเพื่อให้แน่ใจว่ามันถูกสร้างขึ้นโดยคุณ วิธีที่ดีในการบรรลุนี้คือการใช้อัลกอริทึม Luhn


1

นี่คือสิ่งที่ฉันรวมตัวกันอย่างรวดเร็ว

    public string GeneratePassword(int len)
    {
        string res = "";
        Random rnd = new Random();
        while (res.Length < len) res += (new Func<Random, string>((r) => {
            char c = (char)((r.Next(123) * DateTime.Now.Millisecond % 123)); 
            return (Char.IsLetterOrDigit(c)) ? c.ToString() : ""; 
        }))(rnd);
        return res;
    }

1

ฉันใช้รหัสนี้เพื่อสร้างรหัสผ่านที่มีองค์ประกอบความสมดุลของตัวอักษรตัวเลขและตัวอักษรไม่ใช่ _alpha_numeric

public static string GeneratePassword(int Length, int NonAlphaNumericChars)
    {
        string allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789";
        string allowedNonAlphaNum = "!@#$%^&*()_-+=[{]};:<>|./?";
        string pass = "";
        Random rd = new Random(DateTime.Now.Millisecond);
        for (int i = 0; i < Length; i++)
        {
            if (rd.Next(1) > 0 && NonAlphaNumericChars > 0)
            {
                pass += allowedNonAlphaNum[rd.Next(allowedNonAlphaNum.Length)];
                NonAlphaNumericChars--;
            }
            else
            {
                pass += allowedChars[rd.Next(allowedChars.Length)];
            }
        }
        return pass;
    }

0

มันสั้นและใช้งานได้ดีสำหรับฉัน

public static string GenerateRandomCode(int length)
{
    Random rdm = new Random();
    StringBuilder sb = new StringBuilder();

    for(int i = 0; i < length; i++)
        sb.Append(Convert.ToChar(rdm.Next(101,132)));

    return sb.ToString();
}

อาจ "ทำงาน" แต่ไม่ปลอดภัยแน่นอน รหัสผ่านจะต้องปลอดภัย
CodesInChaos

ฉันคิดว่ารหัสผ่านแบบสุ่มเป็นรหัสผ่านชั่วคราว ไม่เห็นว่าทำไมพวกเขาถึงต้องปลอดภัยและแม้ว่าพวกเขาจะทำคุณสามารถเพิ่มตัวเลขและอักขระพิเศษในช่วง
user1058637

1
การเพิ่มตัวเลขและอักขระพิเศษไม่ช่วยปรับปรุงความปลอดภัยหากคุณสร้างขึ้นโดยใช้ PRNG ที่คาดเดาได้ หากคุณรู้ว่าเมื่อใดที่มีการสร้างรหัสผ่านคุณสามารถ จำกัด ให้เหลือเพียงไม่กี่ตัวเลือก
CodesInChaos

0

ในเว็บไซต์ของฉันฉันใช้วิธีนี้:

    //Symb array
    private const string _SymbolsAll = "~`!@#$%^&*()_+=-\\|[{]}'\";:/?.>,<";

    //Random symb
    public string GetSymbol(int Length)
    {
        Random Rand = new Random(DateTime.Now.Millisecond);
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < Length; i++)
            result.Append(_SymbolsAll[Rand.Next(0, _SymbolsAll.Length)]);
        return result.ToString();
    }

แก้ไขสตริง_SymbolsAllสำหรับรายการอาร์เรย์ของคุณ


ตามที่ระบุไว้แล้วในคำอธิบายการแก้ไข หากคุณเชื่อมโยงไปยังเว็บไซต์ของคุณโดยที่ไม่ได้เป็นการอ้างอิงรหัสคุณเป็นการโฆษณาล้วนๆที่ทำให้เกิดสแปมดังนั้นโปรดลบลิงก์นั้นออกจากคำตอบของคุณ
Bowdzone

0

เพิ่มรหัสเสริมเข้าไปในคำตอบที่ยอมรับ มันปรับปรุงตามคำตอบเพียงแค่ใช้แบบสุ่มและช่วยให้ตัวเลือกรหัสผ่านบางอย่าง ฉันชอบตัวเลือกบางส่วนจากคำตอบของ KeePass แต่ไม่ต้องการรวมไฟล์ปฏิบัติการในโซลูชันของฉัน

private string RandomPassword(int length, bool includeCharacters, bool includeNumbers, bool includeUppercase, bool includeNonAlphaNumericCharacters, bool includeLookAlikes)
{
    if (length < 8 || length > 128) throw new ArgumentOutOfRangeException("length");
    if (!includeCharacters && !includeNumbers && !includeNonAlphaNumericCharacters) throw new ArgumentException("RandomPassword-Key arguments all false, no values would be returned");

    string pw = "";
    do
    {
        pw += System.Web.Security.Membership.GeneratePassword(128, 25);
        pw = RemoveCharacters(pw, includeCharacters, includeNumbers, includeUppercase, includeNonAlphaNumericCharacters, includeLookAlikes);
    } while (pw.Length < length);

    return pw.Substring(0, length);
}

private string RemoveCharacters(string passwordString, bool includeCharacters, bool includeNumbers, bool includeUppercase, bool includeNonAlphaNumericCharacters, bool includeLookAlikes)
{
    if (!includeCharacters)
    {
        var remove = new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };
        foreach (string r in remove)
        {
            passwordString = passwordString.Replace(r, string.Empty);
            passwordString = passwordString.Replace(r.ToUpper(), string.Empty);
        }
    }

    if (!includeNumbers)
    {
        var remove = new string[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
        foreach (string r in remove)
            passwordString = passwordString.Replace(r, string.Empty);
    }

    if (!includeUppercase)
        passwordString = passwordString.ToLower();

    if (!includeNonAlphaNumericCharacters)
    {
        var remove = new string[] { "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "-", "_", "+", "=", "{", "}", "[", "]", "|", "\\", ":", ";", "<", ">", "/", "?", "." };
        foreach (string r in remove)
            passwordString = passwordString.Replace(r, string.Empty);
    }

    if (!includeLookAlikes)
    {
        var remove = new string[] { "(", ")", "0", "O", "o", "1", "i", "I", "l", "|", "!", ":", ";" };
        foreach (string r in remove)
            passwordString = passwordString.Replace(r, string.Empty);
    }

    return passwordString;
}

นี่เป็นลิงค์แรกเมื่อฉันค้นหาการสร้างรหัสผ่านแบบสุ่มและต่อไปนี้อยู่นอกขอบเขตของคำถามปัจจุบัน แต่อาจมีความสำคัญที่ต้องพิจารณา

  • ขึ้นอยู่กับข้อสันนิษฐานว่าSystem.Web.Security.Membership.GeneratePasswordมีความปลอดภัยด้วยการเข้ารหัสลับอย่างน้อย 20% ของอักขระที่ไม่ใช่ตัวอักษรและตัวเลข
  • ไม่แน่ใจว่าการลบอักขระและสตริงที่ต่อท้ายนั้นถือว่าเป็นแนวปฏิบัติที่ดีในกรณีนี้และให้ข้อมูลที่เพียงพอ
  • อาจต้องการพิจารณาการใช้งานอย่างใดอย่างหนึ่งกับSecureStringสำหรับการจัดเก็บรหัสผ่านที่ปลอดภัยในหน่วยความจำ

FYI, คุณไม่จำเป็นต้องรวมไฟล์ที่ปฏิบัติการได้ของ KeyPass เนื่องจากมันเป็นโอเพ่นซอร์ส (ซอร์สโค้ดสามารถดาวน์โหลดได้ที่นี่ )
Alex Klaus

0

validChars สามารถสร้างใด ๆ แต่ฉันตัดสินใจที่จะเลือกตามช่วงรหัส ASCII ลบตัวอักษรควบคุม ในตัวอย่างนี้มันเป็นสตริงอักขระ 12 ตัว

string validChars = String.Join("", Enumerable.Range(33, (126 - 33)).Where(i => !(new int[] { 34, 38, 39, 44, 60, 62, 96 }).Contains(i)).Select(i => { return (char)i; }));
string.Join("", Enumerable.Range(1, 12).Select(i => { return validChars[(new Random(Guid.NewGuid().GetHashCode())).Next(0, validChars.Length - 1)]; }))

0
 Generate random password of specified length with 
  - Special characters   
  - Number
  - Lowecase
  - Uppercase

  public static string CreatePassword(int length = 12)
    {
        const string lower = "abcdefghijklmnopqrstuvwxyz";
        const string upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        const string number = "1234567890";
        const string special = "!@#$%^&*";

        var middle = length / 2;
        StringBuilder res = new StringBuilder();
        Random rnd = new Random();
        while (0 < length--)
        {
            if (middle == length)
            {
                res.Append(number[rnd.Next(number.Length)]);
            }
            else if (middle - 1 == length)
            {
                res.Append(special[rnd.Next(special.Length)]);
            }
            else
            {
                if (length % 2 == 0)
                {
                    res.Append(lower[rnd.Next(lower.Length)]);
                }
                else
                {
                    res.Append(upper[rnd.Next(upper.Length)]);
                }
            }
        }
        return res.ToString();
    }

มีเพียงคำตอบที่ได้รับการสนับสนุนเท่านั้นเนื่องจากพวกเขาไม่ได้ให้ข้อมูลมากนักสำหรับผู้อ่านในอนาคตโปรดให้คำอธิบายเกี่ยวกับสิ่งที่คุณเขียน
WhatsThePoint

สร้างรหัสผ่านเดิมซ้ำแล้วซ้ำอีก จำเป็นต้องมีอินสแตนซ์Randomแบบคงที่
trailmax

โปรดทราบว่าคำตอบนี้จะสร้างรหัสผ่านเดียวกันหากถูกเรียกหลายครั้งติดต่อกัน !!! จะต้องมีการเพิ่มเอนโทรปีระหว่างการโทรหากคุณต้องการใช้ฟังก์ชั่นเพื่อกำหนดรหัสผ่านโดยใช้รหัสให้กับหลาย ๆ ระเบียนพร้อมกัน ยังมีประโยชน์แม้ว่า ....
Wizengamot

0

แพคเกจนี้ช่วยให้คุณสามารถสร้างรหัสผ่านแบบสุ่มในขณะที่ระบุอย่างชัดเจนว่าควรใช้อักขระใด (ถ้าจำเป็น):

https://github.com/prjseal/PasswordGenerator/

ตัวอย่าง:

var pwd = new Password().IncludeLowercase().IncludeUppercase().IncludeSpecial();
var password = pwd.Next();

0

หากคุณต้องการใช้ประโยชน์จากการสร้างตัวเลขสุ่มที่ปลอดภัยเข้ารหัสที่ใช้โดย System.Web.Security.Membership.GeneratePassword แต่ยังต้องการ จำกัด ชุดอักขระเป็นอักขระตัวอักษรและตัวเลขคุณสามารถกรองผลลัพธ์ด้วย regex:

static string GeneratePassword(int characterCount)
{
    string password = String.Empty;
    while(password.Length < characterCount)
        password += Regex.Replace(System.Web.Security.Membership.GeneratePassword(128, 0), "[^a-zA-Z0-9]", string.Empty);
    return password.Substring(0, characterCount);
}

-3
public string Sifre_Uret(int boy, int noalfa)
{

    //  01.03.2016   
    // Genel amaçlı şifre üretme fonksiyonu


    //Fonskiyon 128 den büyük olmasına izin vermiyor.
    if (boy > 128 ) { boy = 128; }
    if (noalfa > 128) { noalfa = 128; }
    if (noalfa > boy) { noalfa = boy; }


    string passch = System.Web.Security.Membership.GeneratePassword(boy, noalfa);

    //URL encoding ve Url Pass + json sorunu yaratabilecekler pass ediliyor.
    //Microsoft Garanti etmiyor. Alfa Sayısallar Olabiliyorimiş . !@#$%^&*()_-+=[{]};:<>|./?.
    //https://msdn.microsoft.com/tr-tr/library/system.web.security.membership.generatepassword(v=vs.110).aspx


    //URL ve Json ajax lar için filtreleme
    passch = passch.Replace(":", "z");
    passch = passch.Replace(";", "W");
    passch = passch.Replace("'", "t");
    passch = passch.Replace("\"", "r");
    passch = passch.Replace("/", "+");
    passch = passch.Replace("\\", "e");

    passch = passch.Replace("?", "9");
    passch = passch.Replace("&", "8");
    passch = passch.Replace("#", "D");
    passch = passch.Replace("%", "u");
    passch = passch.Replace("=", "4");
    passch = passch.Replace("~", "1");

    passch = passch.Replace("[", "2");
    passch = passch.Replace("]", "3");
    passch = passch.Replace("{", "g");
    passch = passch.Replace("}", "J");


    //passch = passch.Replace("(", "6");
    //passch = passch.Replace(")", "0");
    //passch = passch.Replace("|", "p");
    //passch = passch.Replace("@", "4");
    //passch = passch.Replace("!", "u");
    //passch = passch.Replace("$", "Z");
    //passch = passch.Replace("*", "5");
    //passch = passch.Replace("_", "a");

    passch = passch.Replace(",", "V");
    passch = passch.Replace(".", "N");
    passch = passch.Replace("+", "w");
    passch = passch.Replace("-", "7");





    return passch;



}

คุณช่วยอธิบายว่าโค้ดของคุณทำอะไรและทำไม? จากรีวิว
Wai Ha Lee

รหัสเฉพาะคำตอบที่ไม่มีคำอธิบายน่าจะถูกลบ
โกง

-4

แทรกตัวจับเวลา: timer1, 2 ปุ่ม: button1, button2, 1 กล่องข้อความ: textBox1 และคอมโบBoxBox: comboBox1 ให้แน่ใจว่าคุณประกาศ:

int count = 0;

รหัสแหล่งที่มา:

 private void button1_Click(object sender, EventArgs e)
    {
    // This clears the textBox, resets the count, and starts the timer
        count = 0;
        textBox1.Clear();
        timer1.Start();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
    // This generates the password, and types it in the textBox
        count += 1;
            string possible = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
            string psw = "";
            Random rnd = new Random { };
            psw += possible[rnd.Next(possible.Length)];
            textBox1.Text += psw;
            if (count == (comboBox1.SelectedIndex + 1))
            {
                timer1.Stop();
            }
    }
    private void Form1_Load(object sender, EventArgs e)
    {
        // This adds password lengths to the comboBox to choose from.
        comboBox1.Items.Add("1");
        comboBox1.Items.Add("2");
        comboBox1.Items.Add("3");
        comboBox1.Items.Add("4");
        comboBox1.Items.Add("5");
        comboBox1.Items.Add("6");
        comboBox1.Items.Add("7");
        comboBox1.Items.Add("8");
        comboBox1.Items.Add("9");
        comboBox1.Items.Add("10");
        comboBox1.Items.Add("11");
        comboBox1.Items.Add("12");
    }
    private void button2_click(object sender, EventArgs e)
    {
        // This encrypts the password
        tochar = textBox1.Text;
        textBox1.Clear();
        char[] carray = tochar.ToCharArray();
        for (int i = 0; i < carray.Length; i++)
        {
            int num = Convert.ToInt32(carray[i]) + 10;
            string cvrt = Convert.ToChar(num).ToString();
            textBox1.Text += cvrt;
        }
    }

1
อย่าใช้System.Randomเพื่อความปลอดภัย
CodesInChaos
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.