如何使用密码和Java将12位十进制数字加密/解密为其他数字?
问题内容:
我已经读过《使用Java加密整数》和《使用通行短语用DES加密》。
我需要的是一个简单的Encrypter,它将具有以下约束的12位数字转换为12位数字:
- 加密必须依赖于密码(在应用程序的整个生命周期中保持不变),而不能依赖其他任何密码。
- 映射必须为1-1(无哈希且多个输入具有相同的输出,反之亦然)。
- 映射不得在不同的VM之间或启动VM时更改(例如,当您重新启动Java时,该实用程序应为您提供相同的映射,这意味着它必须完全取决于所提供的密码)。
- 以0开头的数字不是有效的12位数字(输入的数字也不会以0开头)。
- 密钥/密码永远不可猜测。例如,运行具有多个输入的实用程序并分析输出,不应让人们猜测密钥/密码/哈希或其他内容。
- 所有输入将完全是12位数字,并且少于12位素数(这意味着我们可以使用模算术)。
翻阅文学作品后,我有了这段代码
public void mytestSimple(long code, String password) throws Exception {
SecretKey key = new SecretKeySpec(password.getBytes(), "DES");
Cipher ecipher = Cipher.getInstance("DES");
ecipher.init(Cipher.ENCRYPT_MODE, key);
System.out.println(ecipher.getOutputSize(8));
byte[] encrypted = ecipher.doFinal(numberToBytes(code));
System.out.println(encrypted + "--" + encrypted.length);
Cipher dcipher = Cipher.getInstance("DES");
dcipher.init(Cipher.DECRYPT_MODE, key);
byte[] decrypted = dcipher.doFinal(encrypted);
System.out.println(bytesToNumber(decrypted) + "--" + decrypted.length);
}
public void testSimple() throws Exception {
mytestSimple(981762654986L, "password");
}
我遇到了关于
- 如何将16个字节转换为12位数字。
- 保持1-1映射。
- 在多个VM调用之间保持加密/解密相同。
*我在下面添加的答案*
我添加了一个答案,即从标准Java RSA密钥对生成逻辑中抽出的40位RSA。我仍然需要处理极端情况。我将接受答案并投票赞成“
Tadmas”,我认为这会引导我找到答案。有人可以告诉我我的算法是否很弱/容易受到攻击吗?
问题答案:
我认为Tadmas下面给出的答案非常有帮助,我希望你们在下面破解/欺负我的实现。正如Tadmas指出的,我所有的数字都是40位(12位数字是10 ^
12,大约是2 ^ 40)。
我复制了sun.security.rsa.RSAKeyPairGenerator(链接),并为40位RSA算法创建了自己的生成器。标准之一需要512-1024位,因此我删除了它周围的输入检查。一旦我创建了一个合适的n,e,d值(按照alog,e似乎是65537)。以下代码很好用,
public void testSimple() throws NoSuchAlgorithmException {
MyKeyPairGenerator x = new MyKeyPairGenerator();
x.initialize(40, new SecureRandom("password".getBytes()));
MyPublicPrivateKey keypair = x.generateKeyPair();
System.out.println(keypair);
BigInteger message = new BigInteger("167890871234");
BigInteger encoded = message.modPow(keypair.e, keypair.n);
System.out.println(encoded); //gives some encoded value
BigInteger decoded = encoded.modPow(keypair.d, keypair.n);
System.out.println(decoded); //gives back original value
}
缺点
- 编码的不一定是12位数字(有时可能以0开头,这意味着只有11位数字)。我想总是在前面填充0零,并在开头添加一些CHECKSUM数字,这可以缓解此问题。所以总是13位数…
- 40位RSA的安全性比512位弱(不仅是512/40倍,而且是指数倍)。您能为我指出40位RSA与512位RSA相比有多安全的链接吗(我可以在Wiki中看到某些内容,但无法具体确认受到攻击的可能性)?关于概率/破解N的函数所需的RSA尝试次数/概率的任何链接(wiki?)(其中n是所使用的位数)将非常棒!