简体   繁体   中英

How to generate a 20 byte array of hex values for an X509Certificate2 serial number?

I need to generate a serial number for a self signed X509Certificate. Serial numbers must be a positive integer of 20 bytes

I have a method that generates a random byte array of a given length, but I am having trouble using it to generate a 20 byte array of hex values.

        public static byte[] GenerateRandomByteArray(int Length)
        {
            char[] availableCharacters = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

            var identifier = new char[Length];
            var randomData = new byte[Length];
            var key = new byte[Length];

            using (var rng = new RNGCryptoServiceProvider())
            {
                rng.GetBytes(randomData);
            }

            for (var i = 0; i < identifier.Length; i++)
            {
                var pos = randomData[i] % availableCharacters.Length;
                identifier[i] = availableCharacters[pos];
                key[i] = Convert.ToByte(identifier[i]);
            }
            return key;
        }

Using this method I get serial numbers that are the ToString() representation of the byte's decimal value.

    [0]: 65 'A'
    [1]: 54 '6'
    [2]: 48 '0'
    [3]: 69 'E'
    [4]: 53 '5'
    [5]: 50 '2'
    [6]: 50 '2'
    [7]: 56 '8'
    [8]: 52 '4'
    [9]: 56 '8'
    [10]: 51 '3'
    [11]: 57 '9'
    [12]: 51 '3'
    [13]: 66 'B'
    [14]: 48 '0'
    [15]: 55 '7'
    [16]: 67 'C'
    [17]: 65 'A'
    [18]: 57 '9'
    [19]: 57 '9'

turns into 41 36 30 45 35 32 32 38 34 38 33 39 33 42 30 37 43 41 39 39

How do generate a serial number is the ToString of the hex value?

Do not use System.Random . In comments, you used Random class to generate random portion of the serial number. The problem with Random class is that it is pseudo RNG and returns same random sequence for given seed.

As Dmitry Bychenko pointed out in comments, you misunderstood the requirement. You can use full 0-255 byte value space for every octet in serial number. Limited char table ( [0-9A-F] ) is only hex presentation of byte value. Thus, your solution is simplified to this:

public static byte[] GenerateRandomByteArray(int Length)
{
    var randomData = new byte[Length];
    using (var rng = RandomNumberGenerator.Create())
    {
        rng.GetBytes(randomData);
    }

    return randomData;
}

RNGCryptoServiceProvider is now obsolete and it is recommend to use RandomNumberGenerator factory methods to create appropriate RNG instance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM