SunJCE SHA1WithRSA 使用什么填充策略
what padding strategy is used by SunJCE SHA1WithRSA
通常 PSS
和 PKCS1v15
都可以用于 RSA 签名填充。
而对于java,代码也很简单,就是看不出使用的padding策略。
我的代码:
Signature signature = Signature.getInstance("SHA1WithRSA");
signature.initSign(privateKey);
signature.update(plainBytes);
byte[] signBytes = signature.sign();
我可以将 PSS
和 MGF1
明确定义为使用 SunJCE 作为提供程序的填充策略吗?
PSS
不在 SunJCE. However SHA256withRSA/PSS
is implemented in android 支持的算法列表中。
我建议使用 BouncyCastle
Security.addProvider(new BouncyCastleProvider());
Signature sig = Signature.getInstance("SHA1withRSA/PSS");
sig.initSign(privateKey);
sig.update(data);
byte[] signature = sig.sign();
已更新
PKCS#1 v2.1中的默认maskGenAlgorithm
是MGF1。
RSASSA-PSS-params ::= SEQUENCE {
hashAlgorithm [0] OAEP-PSSDigestAlgorithms DEFAULT sha1,
maskGenAlgorithm [1] PKCS1MGFAlgorithms DEFAULT mgf1SHA1,
saltLength [2] INTEGER DEFAULT 20,
trailerField [3] INTEGER DEFAULT 1
}
我假设 BouncyCastle 正在使用它。您可以定义自己的 PSS 参数。例如(参见 PSSParameterSpec)
sig.setParameter(PSSParameterSpec.DEFAULT);
受答案的启发,只是添加一个片段,显示如何手动设置所有参数,当然必须使用 BouncyCastle
:
Signature signature = Signature.getInstance("SHA256WithRSA/PSS", "BC"); //second param "BC" is not really required
MGF1ParameterSpec mgf1ParameterSpec = new MGF1ParameterSpec("SHA-256");
PSSParameterSpec pssParameterSpec = new PSSParameterSpec("SHA-256", "MGF1", mgf1ParameterSpec , 20, 1);
signature.setParameter(pssParameterSpec);
signature.initSign(privateKey);
signature.update(plainBytes);
byte[] signBytes = signature.sign();
感谢@xuanzhui
以下是我如何成功验证我的(十六进制编码)签名:
public static boolean verify(String plainText, String signature, PublicKey publicKey) throws Exception {
Signature publicSignature = Signature.getInstance("SHA512withRSA/PSS");
publicSignature.setParameter(new PSSParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512 , 64, 1));
publicSignature.initVerify(publicKey);
publicSignature.update(plainText.getBytes(UTF_8));
return publicSignature.verify(hexToBytes(signature));
}
请注意,尽管文档另有建议(getSaltLength()
- "returns the salt length in bits")盐长度似乎在 字节 !
另外我认为 "SHA512withRSA/PSS" 只支持 Android 23+
通常 PSS
和 PKCS1v15
都可以用于 RSA 签名填充。
而对于java,代码也很简单,就是看不出使用的padding策略。
我的代码:
Signature signature = Signature.getInstance("SHA1WithRSA");
signature.initSign(privateKey);
signature.update(plainBytes);
byte[] signBytes = signature.sign();
我可以将 PSS
和 MGF1
明确定义为使用 SunJCE 作为提供程序的填充策略吗?
PSS
不在 SunJCE. However SHA256withRSA/PSS
is implemented in android 支持的算法列表中。
我建议使用 BouncyCastle
Security.addProvider(new BouncyCastleProvider());
Signature sig = Signature.getInstance("SHA1withRSA/PSS");
sig.initSign(privateKey);
sig.update(data);
byte[] signature = sig.sign();
已更新
PKCS#1 v2.1中的默认maskGenAlgorithm
是MGF1。
RSASSA-PSS-params ::= SEQUENCE { hashAlgorithm [0] OAEP-PSSDigestAlgorithms DEFAULT sha1, maskGenAlgorithm [1] PKCS1MGFAlgorithms DEFAULT mgf1SHA1, saltLength [2] INTEGER DEFAULT 20, trailerField [3] INTEGER DEFAULT 1 }
我假设 BouncyCastle 正在使用它。您可以定义自己的 PSS 参数。例如(参见 PSSParameterSpec)
sig.setParameter(PSSParameterSpec.DEFAULT);
受答案的启发,只是添加一个片段,显示如何手动设置所有参数,当然必须使用 BouncyCastle
:
Signature signature = Signature.getInstance("SHA256WithRSA/PSS", "BC"); //second param "BC" is not really required
MGF1ParameterSpec mgf1ParameterSpec = new MGF1ParameterSpec("SHA-256");
PSSParameterSpec pssParameterSpec = new PSSParameterSpec("SHA-256", "MGF1", mgf1ParameterSpec , 20, 1);
signature.setParameter(pssParameterSpec);
signature.initSign(privateKey);
signature.update(plainBytes);
byte[] signBytes = signature.sign();
感谢@xuanzhui
以下是我如何成功验证我的(十六进制编码)签名:
public static boolean verify(String plainText, String signature, PublicKey publicKey) throws Exception {
Signature publicSignature = Signature.getInstance("SHA512withRSA/PSS");
publicSignature.setParameter(new PSSParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512 , 64, 1));
publicSignature.initVerify(publicKey);
publicSignature.update(plainText.getBytes(UTF_8));
return publicSignature.verify(hexToBytes(signature));
}
请注意,尽管文档另有建议(getSaltLength()
- "returns the salt length in bits")盐长度似乎在 字节 !
另外我认为 "SHA512withRSA/PSS" 只支持 Android 23+