Generating a unique *and* random URL in C#

南笙酒味 提交于 2019-12-03 12:05:47
Josh

A Guid is not meant to be a security feature. The standards for creating a Guid make no claims about how secure it is, or how easy/hard it is to guess. It simply makes a claim about it's uniqueness.

If you attempt to secure your system by using a Guid then you will not have a secure system.

[Edit: I missed the call to RNGCryptoServiceProvider above. Apologies about that.]

The problem with RNG generators like the RNGCryptoServiceProvider for your case is they do not guarantee uniqueness. Guids, as you know, are statistically unlikely to be unique but do not guarantee it. The only real way to guarantee both uniqueness and randomness is to generate the GUID like you have then put it in a searchable store, like a database table. Whenever you generate a new value, check it is not already present. If it is, discard it and generate a new value.

You can generate 128 bit, "random," unique numbers by running a counter through an AES counter keyed with a random key. As long as the same key is used this will never repeat any output.

static byte[] AESCounter(byte[] key, ulong counter) {
    byte[] InputBlock = new byte[16];
    InputBlock[0] = (byte)(counter & 0xffL);
    InputBlock[1] = (byte)((counter & 0xff00L) >> 8);
    InputBlock[2] = (byte)((counter & 0xff0000L) >> 16);
    InputBlock[3] = (byte)((counter & 0xff000000L) >> 24);
    InputBlock[4] = (byte)((counter & 0xff00000000L) >> 32);
    InputBlock[5] = (byte)((counter & 0xff0000000000L) >> 40);
    InputBlock[6] = (byte)((counter & 0xff000000000000L) >> 48);
    InputBlock[7] = (byte)((counter & 0xff00000000000000L) >> 54);
    using (AesCryptoServiceProvider AES = new AesCryptoServiceProvider())
    {
        AES.Key = key;
        AES.Mode = CipherMode.ECB;
        AES.Padding = PaddingMode.None;
        using (ICryptoTransform Encryptor = AES.CreateEncryptor())
        {
            return Encryptor.TransformFinalBlock(InputBlock, 0, 16);
        }
    }
}

Get md5 of of all the user login credentials and the concatenate it with the guid generated by Guid.NewGuid().ToString() and use it in your url, it should work fine.

Spegah

Create a table in the database with a linkID and a Datesent column, on generation of the link send insert DateTime.Now into the table and return linkId, set the linkID as a querystring parameter on the activationLink.

On load of the activation page retrive the linkId and use it to evoke a stored procedure that will return the date when passed the corresponding linkId as a parameter, when you get the date back you can add how long you want the link to stay active by using the .AddDays()/.AddMonths (this are C# methods for datetime). Then compare the date you got back with today's date. If it has passed its length of days or months give an error message or else continue and display the page content.

I sugest you keep the contents of the page in a panel and and set it visible = "false" then only make the panel visible="true" if the date is still within range.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!