BouncyCastle,桌面签名的不同行为/Android
BouncyCastle, different behaviour for signature on Desktop / Android
我使用以下代码来签署数据:
static public byte[] sign(byte[] data, PrivateKey privateKey, int saltLength) throws Exception {
Signature instance = Signature.getInstance("SHA256withRSA/PSS", provider);
MGF1ParameterSpec mgf1ParameterSpec = new MGF1ParameterSpec("SHA-256");
PSSParameterSpec pssParameterSpec = new PSSParameterSpec("SHA-256", "MGF1",mgf1ParameterSpec , saltLength, 1);
instance.setParameter(pssParameterSpec);
instance.initSign(privateKey);
instance.update(data);
return instance.sign();
}
(检查符号的代码非常相似)
在桌面上,代码运行良好,可以用其他平台检查签名(用 python、节点等测试)。
在 Android 上,"saltLength" 未被读取,并且被强制为 32 位,因此如果另一个 "saltLength" 是,我无法从其他平台上的设备签名/验证签名用过的。 (我通过在桌面上强制使用 saltLength 值来验证它)。
我真的不知道如何调试它,同样的 Java 代码在桌面上启动或 Android 上有不同的行为。知道如何在 Android 上强制 "saltLength" 吗?
好的,在桌面和 Android 端进行了多次测试之后...
我仍然没有找到问题的根源(我猜测 java.security.Signature$SignatureImpl
的不同实现,但不确定 ...)
但是,对于遇到相同问题的任何人,我都找到了解决方法。
我创建了以下 class:
public class SHA256withRSACustomPadding extends PSSSignatureSpi {
public SHA256withRSACustomPadding(int padding) {
super(new RSABlindedEngine(), new PSSParameterSpec("SHA-256", "MGF1", new MGF1ParameterSpec("SHA-256"), padding, 1));
}
public void initSign(PrivateKey privateKey) throws InvalidKeyException {
engineInitSign(privateKey);
}
public void update(byte[] data) throws SignatureException {
engineUpdate(data,0,data.length);
}
public byte[] sign() throws SignatureException {
return engineSign();
}
public void initVerify(PublicKey publicKey) throws InvalidKeyException {
engineInitVerify(publicKey);
}
public boolean verify(byte[] data) throws SignatureException {
return engineVerify(data);
}
}
并更新了我之前的代码:
static public byte[] sign(byte[] data, PrivateKey privateKey, int saltLength) throws Exception {
SHA256withRSACustomPadding instance = new SHA256withRSACustomPadding(padding);
instance.initSign(privateKey);
instance.update(data);
return instance.sign();
}
我使用以下代码来签署数据:
static public byte[] sign(byte[] data, PrivateKey privateKey, int saltLength) throws Exception {
Signature instance = Signature.getInstance("SHA256withRSA/PSS", provider);
MGF1ParameterSpec mgf1ParameterSpec = new MGF1ParameterSpec("SHA-256");
PSSParameterSpec pssParameterSpec = new PSSParameterSpec("SHA-256", "MGF1",mgf1ParameterSpec , saltLength, 1);
instance.setParameter(pssParameterSpec);
instance.initSign(privateKey);
instance.update(data);
return instance.sign();
}
(检查符号的代码非常相似)
在桌面上,代码运行良好,可以用其他平台检查签名(用 python、节点等测试)。
在 Android 上,"saltLength" 未被读取,并且被强制为 32 位,因此如果另一个 "saltLength" 是,我无法从其他平台上的设备签名/验证签名用过的。 (我通过在桌面上强制使用 saltLength 值来验证它)。
我真的不知道如何调试它,同样的 Java 代码在桌面上启动或 Android 上有不同的行为。知道如何在 Android 上强制 "saltLength" 吗?
好的,在桌面和 Android 端进行了多次测试之后...
我仍然没有找到问题的根源(我猜测 java.security.Signature$SignatureImpl
的不同实现,但不确定 ...)
但是,对于遇到相同问题的任何人,我都找到了解决方法。 我创建了以下 class:
public class SHA256withRSACustomPadding extends PSSSignatureSpi {
public SHA256withRSACustomPadding(int padding) {
super(new RSABlindedEngine(), new PSSParameterSpec("SHA-256", "MGF1", new MGF1ParameterSpec("SHA-256"), padding, 1));
}
public void initSign(PrivateKey privateKey) throws InvalidKeyException {
engineInitSign(privateKey);
}
public void update(byte[] data) throws SignatureException {
engineUpdate(data,0,data.length);
}
public byte[] sign() throws SignatureException {
return engineSign();
}
public void initVerify(PublicKey publicKey) throws InvalidKeyException {
engineInitVerify(publicKey);
}
public boolean verify(byte[] data) throws SignatureException {
return engineVerify(data);
}
}
并更新了我之前的代码:
static public byte[] sign(byte[] data, PrivateKey privateKey, int saltLength) throws Exception {
SHA256withRSACustomPadding instance = new SHA256withRSACustomPadding(padding);
instance.initSign(privateKey);
instance.update(data);
return instance.sign();
}