Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中生成唯一的*和*随机URL#_C#_Security_Authentication_Cryptography_Guid - Fatal编程技术网

C# 在C中生成唯一的*和*随机URL#

C# 在C中生成唯一的*和*随机URL#,c#,security,authentication,cryptography,guid,C#,Security,Authentication,Cryptography,Guid,我的最终目标是创建一个唯一且无法猜测/预测的URL。此URL的目的是允许用户执行验证其电子邮件地址和重置密码等操作。这些URL将在设定的时间内过期(当前设置为24小时) 我最初使用的是Guid,但现在我知道这介于“很好”和“非常不安全”之间,这取决于你听的是哪位专家。所以,我想我应该加强我的代码,以防万一。起初我认为我应该坚持使用Guid,但它是从随机字节生成的,而不是Guid.NewGuid()工厂方法。以下是我提出的方法: public static Guid GetRandomGuid()

我的最终目标是创建一个唯一且无法猜测/预测的URL。此URL的目的是允许用户执行验证其电子邮件地址和重置密码等操作。这些URL将在设定的时间内过期(当前设置为24小时)

我最初使用的是
Guid
,但现在我知道这介于“很好”和“非常不安全”之间,这取决于你听的是哪位专家。所以,我想我应该加强我的代码,以防万一。起初我认为我应该坚持使用
Guid
,但它是从随机字节生成的,而不是
Guid.NewGuid()
工厂方法。以下是我提出的方法:

public static Guid GetRandomGuid()
{
    var bytes = new byte[16];
    var generator = new RNGCryptoServiceProvider();
    generator.GetBytes(bytes);
    return new Guid(bytes);
}
我不太清楚使用
NewGuid(bytes)
而不是
Guid.NewGuid()
时会发生什么,但我认为这种方法所做的只是生成一个随机字节数组并将其存储在
Guid
数据结构中。换句话说,它不再保证是唯一的,它只保证是随机的

由于我的URL需要是唯一的和随机的,这似乎不是一个可靠的解决方案。我现在在想,我的URL应该基于一个唯一ID(可以是
Guid
,或者,如果可用,数据库自动递增ID)和从
RNGCryptoServiceProvider
生成的随机序列的组合

问题

生成保证唯一且极难/不可能预测/猜测的验证/密码重置URL的最佳方法是什么

  • 我是否应该简单地通过将唯一字符串与随机字符串连接来构造URL

  • NET Framework是否有一种内置方式可以轻松生成可用于URL的唯一且随机(不可预测)的序列

  • 如果没有,是否有一个好的开源解决方案

更新

如果有人有类似的要求,我目前正在使用以下方法:

public static string GenerateUniqueRandomToken(int uniqueId)
    // generates a unique, random, and alphanumeric token
{
    const string availableChars =
        "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    using (var generator = new RNGCryptoServiceProvider())
    {
        var bytes = new byte[16];
        generator.GetBytes(bytes);
        var chars = bytes
            .Select(b => availableChars[b % availableChars.Length]);
        var token = new string(chars.ToArray());
        return uniqueId + token;
    }
}

如果您发现这方面有任何问题,请发表意见。

Guid并不意味着是一种安全功能。创建Guid的标准,或者猜测它有多容易/难它只是宣称它的独特性。


如果您试图使用Guid保护您的系统,则您将无法获得安全的系统。

[编辑:我错过了与上述RNGCryptoServiceProvider的通话。对此深表歉意。]

对于您的案例,RNG生成器(如RNGCryptoServiceProvider)的问题在于它们不能保证唯一性。正如您所知,guid是唯一的,但不能保证它是唯一的。保证唯一性和随机性的唯一真正方法是生成GUID,就像您将其放入可搜索存储区(如数据库表)中一样。每当生成新值时,请检查该值是否尚未存在。如果是,则丢弃它并生成一个新值。

您可以通过使用随机密钥键入的AES计数器运行计数器来生成128位“随机”唯一数字。只要使用相同的键,就不会重复任何输出

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);
        }
    }
}

获取所有用户登录凭据的md5,并将其与guid.NewGuid().ToString()生成的guid连接起来,并在url中使用它,它应该可以正常工作。

在数据库中创建一个带有linkID和Datesent列的表,在生成链接send insert
DateTime时。现在将
插入到表中并返回linkID,将linkID设置为activationLink上的querystring参数

加载激活页面时,检索linkId并使用它调用一个存储过程,该存储过程将返回作为参数传递相应linkId时的日期,当您返回日期时,您可以使用
.AddDays()
/
.AddMonths
(这是datetime的C方法)添加希望链接保持活动的时间。然后比较你回来的日期和今天的日期。如果超过了天数或月份,则给出错误消息,否则继续并显示页面内容


我建议您将页面内容保留在面板中,并将其设置为
visible=“false”
,然后仅在日期仍在范围内时才将面板设置为
visible=“true”

答案对您有帮助吗?我怀疑这将是您的最佳选择。它显然不符合GUID标准。看起来您只是创建了一个16字节的随机数,而不是GUID。@Gabe,是的,请参阅我的编辑。似乎只是生成一个GUID,然后使用该GUID的哈希将为您提供所需的(唯一性和随机性)。我的代码过去只是
GUID.NewGuid()
。我编写上述方法是为了提高安全性。我尝试使用此方法所做的是使用加密随机数生成器生成字节,然后简单地将这些字节存储在
Guid
数据结构中(用于数据库存储)。这不是我的代码所做的吗?如果不是,你有什么建议?我使用
Guid
s为密码重置等生成唯一的URL。所有这些URL在发布后24小时过期。我认为问题在于Guid本质上是可预测的,因为它遵循特定的规则。为什么不根据您自己的一组规则创建一个随机加密散列呢。您可以根据用户名和特定于服务器设置的其他信息进行设置。。。如果不熟悉您的服务器,这基本上是不可能猜测的。GUID是特定的,规则是已知的,因此它在理论上是可以猜测的,尽管在数学上是不可能的。哈希的问题是它不能保证是唯一的。我很确定我在这里所做的也不能保证是独一无二的。但我需要唯一性和随机性。请仔细查看我的代码。我已经在使用RNGCrptoServiceProvider了。@DanM我深表歉意。我重写了我的作品