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

时间:2010-11-13 07:24:09

标签: passwords

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

我假设唯一的方法是生成仅在特定日期集之间工作的密码。谁能推荐一种可以做到这一点的算法?它不一定非常安全,我知道你可以通过重置PC上的时间来解决这个问题!

感谢。

3 个答案:

答案 0 :(得分:3)

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

为了防止它在另一台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 =

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

答案 1 :(得分:1)

您的应用程序应具有类似此类密码的有效性属性

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

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

答案 2 :(得分:0)

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