如何生成与日期相关的密码?

发布于 2024-10-02 09:45:33 字数 293 浏览 0 评论 0原文

我正在寻找一种简单的方法来生成密码,该密码只能在有限的时间内使用一次,例如 1 天、1 周、1 个月。这必须在没有连接的应用程序中实现,因此不可能使用服务器。用例是这样的: 1. 生成特定日期和时间长度的密码。 2. 发送给用户(电子邮件、电话等)。 3. 用户进入应用程序。 4. 应用程序在特定时间启用。 5. 密码不能重复使用,即使在另一台电脑上也是如此。

我假设执行此操作的唯一方法是生成仅在特定日期集之间有效的密码。谁能推荐一个可以做到这一点的算法?它不必非常安全,而且我知道您可以通过重置 PC 上的时间来破解这个问题!

谢谢。

I'm looking for a simple way to generate passwords that will only work once for a limited amount of time, e.g. 1 day, 1 week, 1 month. This has to be implemented in an application that has no connectivity so a server isn't possible. The use case is something like:
1. Generate password for a specific date and length of time.
2. Send to user (email, phone, etc).
3. User enters in application.
4. Application is enabled for a specific time.
5. Password cannot be reused, even on another PC.

I'm assuming the only way to do this is to generate passwords that only work between a specific set of dates. Can anyone recommend an algorithm that can do this? It doesn't have to be incredibly secure, and I know you can crack this by resetting the time on the PC!

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

输什么也不输骨气 2024-10-09 09:45:33

我知道我迟到了,但无论如何我都会提供我的建议,以防其他需要它的人找到这里。

为了防止它在另一台 PC 上使用,您可以使用 MAC 地址或硬件地址。但是,这取决于检查密码时网络硬件仍然可用。请确保您使用将检查密码的机器的硬件地址。

    private string GetBase64Mac()
    {
        System.Net.NetworkInformation.NetworkInterface[] interfaces = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
        if (interfaces.Length == 0)
        {
            System.Net.NetworkInformation.PhysicalAddress add = interfaces[0].GetPhysicalAddress();
            if (add != null)
                return System.Convert.ToBase64String(add.GetAddressBytes());
        }
        return "";
    }

要限制某个到期日期,只需使用到期日期的文本字符串即可。

    private string GetExpiryDate(DateTime expiryDate)
    {
        return expiryDate.ToString("yyyyMMdd");
    }

只需使用散列函数对组合到期日期、硬件地址和密钥进行散列即可。在哈希输出中添加到期日期的前缀或后缀。

    private void GeneratePassword(string prefix)
    {
        string secretKey = "MySecretKey";
        System.Security.Cryptography.SHA1 sha = System.Security.Cryptography.SHA1.Create();
        byte[] preHash = System.Text.Encoding.UTF32.GetBytes(prefix + secretKey + GetBase64Mac());
        byte[] hash = sha.ComputeHash(preHash);
        string password = prefix + System.Convert.ToBase64String(hash);
        return password;
    }

在上面的例子中,我在哈希值前加上了到期日期。因此,当我们检查密码时,我们只需从密码中提取到期日期,使用相同的函数生成相同的密码。如果生成的密码与提供的密码匹配,则绿灯亮起。

    private void TestPassword()
    {
        int duration = 15; // in days
        string prefix = GetExpiryDate(DateTime.Today.AddDays(duration));
        string generated = GeneratePassword(prefix);

        // Positive test
        string testPrefix = generated.Substring(0, 8);
        string testPassword = GeneratePassword(testPrefix);

        if (generated != TestPassword)
            return false;

        // Negative test
        generated[2] = '2';
        generated[12] = 'b';

        testPrefix = generated.Substring(0, 8);
        testPassword = GeneratePassword(testPrefix);
        if (generated != TestPassword)
            return true;

        return false;
    }

输出密码示例:

20110318k3X3GEDvP0LkBN6zCrkijIE+sNc=

如果无法获取硬件地址,则只需使用客户的名称即可。它不会阻止密码在多台计算机上使用,但会确保同一个人在使用它。

I know I'm late but I'll provide my advice anyway in case someone else who needs it found their way here.

To prevent it being used on another PC, you could probably use the MAC address or hardware address. However, this is subject to the network hardware being still available when checking the password. Please make sure you use the hardware address of the machine where the password will be checked.

    private string GetBase64Mac()
    {
        System.Net.NetworkInformation.NetworkInterface[] interfaces = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
        if (interfaces.Length == 0)
        {
            System.Net.NetworkInformation.PhysicalAddress add = interfaces[0].GetPhysicalAddress();
            if (add != null)
                return System.Convert.ToBase64String(add.GetAddressBytes());
        }
        return "";
    }

To limit it by some expiry date simply use the text string of the expiry date.

    private string GetExpiryDate(DateTime expiryDate)
    {
        return expiryDate.ToString("yyyyMMdd");
    }

Simply use a hash function to hash the combine expiry date, hardware address and a secret key. Prefix or suffix the hash output with the expiry date.

    private void GeneratePassword(string prefix)
    {
        string secretKey = "MySecretKey";
        System.Security.Cryptography.SHA1 sha = System.Security.Cryptography.SHA1.Create();
        byte[] preHash = System.Text.Encoding.UTF32.GetBytes(prefix + secretKey + GetBase64Mac());
        byte[] hash = sha.ComputeHash(preHash);
        string password = prefix + System.Convert.ToBase64String(hash);
        return password;
    }

In the case above, i prefix the hash with the expiry date. So, when we check the password, we simply extract the expiry date from the password, use the same function to generate the same password. If the generated password match the provided password, then you have green light.

    private void TestPassword()
    {
        int duration = 15; // in days
        string prefix = GetExpiryDate(DateTime.Today.AddDays(duration));
        string generated = GeneratePassword(prefix);

        // Positive test
        string testPrefix = generated.Substring(0, 8);
        string testPassword = GeneratePassword(testPrefix);

        if (generated != TestPassword)
            return false;

        // Negative test
        generated[2] = '2';
        generated[12] = 'b';

        testPrefix = generated.Substring(0, 8);
        testPassword = GeneratePassword(testPrefix);
        if (generated != TestPassword)
            return true;

        return false;
    }

Sample output password:

20110318k3X3GEDvP0LkBN6zCrkijIE+sNc=

If you can't get the hardware address, then simply use the customer's name. It won't prevent the password from being used in multiple machines, but it will ensure that the same person is using it.

爱殇璃 2024-10-09 09:45:33

您的应用程序应该具有诸如密码有效性之类的属性

username password_hash validity_from  Validity_end
xyz      a73839$56     11-Nov-2010    12-Nov-2010

,然后在您的应用程序中您可以验证您的密码是否已过期

Your application should have a attribute like validity for the password something like this

username password_hash validity_from  Validity_end
xyz      a73839$56     11-Nov-2010    12-Nov-2010

and then in your application you can validate that your password has expired or not

陪你到最终 2024-10-09 09:45:33

通过您喜欢的任何方法(单词列表、随机字母等)生成密码。将它们放入某种数据结构中,例如关联数组,您可以在其中将日期与每个密码关联起来。然后,您在分发密码的程序中查阅该数据结构,以给出具有正确到期日期的密码。客户端程序具有相同的密码和日期列表,因此当它获取密码时,它只是查找相关的到期日期。

Generate passwords by any method you'd like (a word list, random letters, etc). Put them into some data structure, like an associative array, where you can associate a date with each password. Then you consult this data structure in the program that hands out passwords to give one out with the proper expiration date. The client program has the same list of passwords and dates, so when it gets a password, it just looks up the associated expiration date there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文