首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >根据输入编号生成随机密钥

根据输入编号生成随机密钥
EN

Stack Overflow用户
提问于 2017-08-18 13:12:56
回答 1查看 959关注 0票数 1

我有一个整数列表(emplyoee ID),它们有8位长(虽然几乎都是从00开始,但实际上是8位长)。

对于每个员工,我需要生成一个密钥,即:

代码语言:javascript
复制
- 5 chars including [A-Z][a-z][0-9]
- Must include 1 of [A-Z]
- Must include 1 of [0-9]
- Generated key must be unique
- If I know an employees ID I should not be able to determine their key

我需要生成一个生成密钥的算法,但如果可能的话,我希望避免不得不记录针对员工的密钥。我想得越多,遇到的问题就越多。

如果我能避免它,我不想生成所有的密钥并将它们存储在某个地方--我宁愿它们是临时计算出来的。

我被允许在我的系统中隐藏一个秘密,除非你知道这个秘密,否则我可以用它来确保密钥是不确定的。

我想使用标准的散列算法(使用salt),但是目标空间的限制和包含1A-Z和10-9的限制似乎阻止了这一点。

我想我可以用一个方法来解决这个问题:

代码语言:javascript
复制
1. Build a deteremnistic function that maps integers starting from 1 [1, 2, 3, ...] to every possible result value
2. Map integers [1, 2, ...] to random other integers in the desired range [324, 43565, ...] in a way that preserves uniqueness (based on a secret salt which if changed would result in a different order).

这将保证唯一性,但是步骤1是很棘手的。结果集是不连续的,一些值可能缺少大写字母,而其他值可能会遗漏一个数字。

我可以通过使用A1启动每一段代码,这在技术上是可行的,但将结果空间从5个字符减少到3个字符。

有人能提出一些简单的建议吗?这样可以避免我为了唯一的检查而保存所有生成的结果的记录?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-18 16:12:24

正如拉尔夫所提到的,实现所需的键量变化的最简单方法可能是更改大写字母和数字的位置,为您提供2 * 26 * 10 * 62 * 62 * 62>120000000可能的组合。

为了使密钥不能直接从员工ID派生,我建议一个简单的XOR与另一个秘密8位数。然后对每个字符使用一个简单的模数,然后再加上除法。

代码语言:javascript
复制
char = x % 62
x = (x - (x % 62)) / 62

例如,在javascript中:

代码语言:javascript
复制
function ID2Key(id, secret) {
    var table = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    var key = new Array(5); // Initialize the key
    // Changed XOR to a ROT10
    // var scrambled = id ^ secret; // "Encrypt" the employee ID with a secret
    var scrambled = 0;
    while (id) {
        var rotated = ((id % 10) + (secret % 10)) % 10;
        scrambled = (scrambled * 10) + rotated;
        id = Math.floor(id / 10);
        secret = Math.floor(secret / 10)
    }

    var capital_index = scrambled % 2; // Determine if the Capital letter should be first
    scrambled = (scrambled - capital_index) / 2;
    var capital = table[36 + (scrambled % 26)]; // Find the capital letter
    key[capital_index] = capital;
    scrambled = (scrambled - (scrambled % 26)) / 26;

    var num = scrambled % 10; // Find the number
    key[1-capital_index] = table[num]; // If the capital letter is first place the number second and visa versa
    scrambled = (scrambled - (scrambled % 10)) / 10;

    // Find the remaining 3 characters
    key[2] = table[scrambled % 62];
    scrambled = (scrambled - (scrambled % 62)) / 62;

    key[3] = table[scrambled % 62];
    scrambled = (scrambled - (scrambled % 62)) / 62;

    key[4] = table[scrambled % 62];
    return key.join("");
}

现场演示JS Bin

解决异或故障的编辑-为了解决注释中提到的失败案例,我改变了将ID置乱为基于秘密的旋转的方法,这个秘密现在也可以是一个8位数的数字。

编辑澄清了漏洞--因为我现在更好地理解了需求,主要是员工将知道他们的ID和密钥,所以我应该澄清一些密码概念。由于输入范围很小,输出受限,因此不可能使密钥具有加密安全性。即使使用一个完善的加密算法,如128位AES,最终的强度也不会比100000000蛮力试图破解的效果更好,这是不需要计算的。考虑到这一点,拥有某种安全外观的唯一方法是秘密算法保持秘密。在这种情况下,尝试从ID和密钥获得秘密的人无法知道他们是正确的,除非他们能够访问多个ID-密钥对。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45757569

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档