Encryption 节点rsa中使用MD5和MGF1填充的OAEP
我正试图找出如何在节点RSA中使用OAEPwithMD5和MGF1填充进行RSA加密 下面是我在node.js中的代码Encryption 节点rsa中使用MD5和MGF1填充的OAEP,encryption,rsa,Encryption,Rsa,我正试图找出如何在节点RSA中使用OAEPwithMD5和MGF1填充进行RSA加密 下面是我在node.js中的代码 var NodeRSA = require('node-rsa'); var fs = require('fs'); var publicKey = '-----BEGIN PUBLIC KEY-----\n*****\n-----END PUBLIC KEY-----'; var privateKey = '-----BEGIN RSA PRI
var NodeRSA = require('node-rsa');
var fs = require('fs');
var publicKey = '-----BEGIN PUBLIC KEY-----\n*****\n-----END PUBLIC KEY-----';
var privateKey = '-----BEGIN RSA PRIVATE KEY-----\n*****\n-----END RSA PRIVATE KEY-----'
const constants = require('constants');
var options1 = {
environment: 'node',
encryptionScheme: {
scheme: 'pkcs1_oaep',
hash: 'md5', //hash using for scheme
}
}
var text = 'This is the string to be encrypted using RSA!';
var encryptKey = new NodeRSA(publicKey, 'pkcs8-public', options1);
encryptKey.setOptions(options1)
var encrypted = encryptKey.encrypt(text, 'base64');
console.log(encrypted);
console.log(encryptKey.isPublic(true))
var options2 = {
environment: 'node',
encryptionScheme: {
scheme: 'pkcs1_oaep', //scheme
hash: 'md5', //hash using for scheme
}
}
var decryptKey = new NodeRSA(privateKey, 'pkcs1', options2);
decryptKey.setOptions(options2)
var decrypted = decryptKey.decrypt(encrypted, 'utf8');
console.log('decrypted: ', decrypted);
运行上述代码的结果
f1zi49yKJSqkWW2J3Jt2lf1fe79JgqufFawYESOJRqhM4YEcGQBcaP39yptn7vShhsJBCTUOsbiV1YcW/YUzoaSQzX9YU0iTMara7h+LNLUrq4FZ2twy5X3uyAP1sUD1SnvQvlRJqrAh23UAwnx31rv6ySC+XgpLPR7wHYaDbSgyQKiF3qhGRj2SIAZ6weziNPfEm9FifBVjnWMvGDQYbjLbanbnSriN+bWpRtXKH9pQqMoskkiMwCviJdKtKzz/vVr0littPLnw0ojbsGSPKQPS3U3xCH3QiBmxEegc0uy3sJdk6aH/2SMuoPzGu7VS+PsLQctxnvKNnC9qsLFWyA==
true
decrypted: This is the string to be encrypted using RSA!
下面是我用JAVA编写的代码
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import javax.crypto.Cipher;
public class DecryptATT {
public static void main(String[] args) throws Exception {
String encryptedData = "f1zi49yKJSqkWW2J3Jt2lf1fe79JgqufFawYESOJRqhM4YEcGQBcaP39yptn7vShhsJBCTUOsbiV1YcW/YUzoaSQzX9YU0iTMara7h+LNLUrq4FZ2twy5X3uyAP1sUD1SnvQvlRJqrAh23UAwnx31rv6ySC+XgpLPR7wHYaDbSgyQKiF3qhGRj2SIAZ6weziNPfEm9FifBVjnWMvGDQYbjLbanbnSriN+bWpRtXKH9pQqMoskkiMwCviJdKtKzz/vVr0littPLnw0ojbsGSPKQPS3U3xCH3QiBmxEegc0uy3sJdk6aH/2SMuoPzGu7VS+PsLQctxnvKNnC9qsLFWyA==";
// Cipher decrypt = Cipher.getInstance("RSA/ECB/OAEPwithMD5andMGF1Padding");
Cipher decrypt = Cipher.getInstance("RSA/ECB/OAEPwithSHA1andMGF1Padding");
RSAPrivateKey privateKey = getPrivateKey();
System.out.println("test");
decrypt.init(Cipher.DECRYPT_MODE, privateKey);
byte[] original = decrypt.doFinal(Base64.getDecoder().decode(encryptedData));
System.out.println(new String(original));
}
public static RSAPrivateKey getPrivateKey() throws Exception {
String keyPath = "/Users/C.SubbiahVeluAngamuthu/Desktop/Samsung/Docs/att/Keys/3_my_testing/pkcs8_key";
File privKeyFile = new File(keyPath);
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(new FileInputStream(privKeyFile));
} catch (FileNotFoundException e) {
throw new Exception("Could not locate keyfile at '" + keyPath + "'", e);
}
byte[] privKeyBytes = new byte[(int) privKeyFile.length()];
bis.read(privKeyBytes);
bis.close();
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
KeySpec ks = new PKCS8EncodedKeySpec(privKeyBytes);
RSAPrivateKey privKey = (RSAPrivateKey) keyFactory.generatePrivate(ks);
return privKey;
}
}
下面是运行JAVA代码的结果
test
This is the string to be encrypted using RSA!
但是当我将密码实例从RSA/ECB/oaepwithsha1和mgf1padding
更改为“RSA/ECB/oaepwithmd5和mgf1padding”
(我假设它是我在node.js程序的encryptionScheme中提到的)时,它抛出以下错误
test
Exception in thread "main" javax.crypto.BadPaddingException: Decryption error
at sun.security.rsa.RSAPadding.unpadOAEP(RSAPadding.java:499)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:293)
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:363)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)
at javax.crypto.Cipher.doFinal(Cipher.java:2165)
at DecryptATT.main(DecryptATT.java:26)
谁能帮我看看哪里出了问题吗?由
- OAEP使用的哈希
,其八位字节宽度标注为hash
hLen
- 公钥的大小,
octetsk
- OAEP使用的掩码生成函数(MGF)
hash'
参数化,它的八位字节宽度标注为hLen'
(标准中没有“
,我正在编这个符号)
你猜对了,没有说明Hash
和Hash'
是相同的,甚至hLen
=hLen'
而且,相信我,除非对它做了一些特殊的处理,否则在典型的Java环境下,“RSA/ECB/OAEPwithMD5andMGF1Padding”
(如果支持的话)将使用MD5表示散列
,但默认为SHA-1表示散列
;当node.js可能同时使用MD5时
面对SHA-256而不是MD5的类似问题,我们可以强制nice Java运行时对其执行正确的操作
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
cipher.init(Cipher.DECRYPT_MODE, privKey, new OAEPParameterSpec(
"SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT
));
我担心您不会这么幸运,因为似乎从来没有MD5说明符;但在放弃之前,不妨尝试一下新的MGF1ParameterSpec(“MD5”)
如果你真的需要在Java下完成这项工作,一个选择是在“RSA/ECB/NoPadding”调用的Cipher
之上使用MD5滚动RSAES-OAEP,这将执行教科书式的RSA,迄今为止最复杂的构造块(至少,所有的密钥管理、模块化算法和卸载到HSM的能力都得到了解决)。这是几十行代码,包括MFG1
另一个选择可能是
即使在MFG1中,继续使用MD5也不是一个好主意。如果对手能够在知道消息的某一部分之前选择该部分,那么将其用作主要散列是一场彻头彻尾的灾难。如果有疑问,不要使用MD5使用MD5生成签名是错误的,句号。MD5已损坏,请勿使用。甚至对于MGF1也不是。