【发布时间】:2015-12-03 13:11:05
【问题描述】:
我正在开发一个需要对 html 文档进行数字签名的 Android 应用程序。 该文档以 JSON 形式驻留在数据库中。 我正在使用我在其他一些 SO 问题上找到的 BASH 脚本在本地签署文档:
openssl dgst -sha1 someHTMLDoc.html > hash
openssl rsautl -sign -inkey privateKey.pem -keyform PEM -in hash > signature.bin
私钥是使用生成的:
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:3 -out privateKey.pem
公钥是使用生成的:
openssl pkey -in privateKey.pem -out publicKey.pem -pubout
我想在应用程序中验证 Signature.bin 中创建的签名以及 someHTMLDoc.html 中的数据。
我将 html 和签名都作为 JSON 对象发送:
{ "data" : "<html><body></body></html>", "signature":"6598 13a9 b12b 21a9 ..... " }
android 应用程序将 PublicKey 保存在共享首选项中,如下所示:
-----BEGIN PUBLIC KEY-----
MIIBIDANBgkqhkiG9w0AAAEFAAOCAQ0AvniCAKCAQEAvni/NSEX3Rhx91HkJl85
\nx1noyYET ......
注意其中的 "\n"(换行符)(在将字符串从 publicKey.pem 复制到 Android Gradle Config 时自动添加。
好的,经过所有准备,现在是问题所在。 我正在尝试验证密钥,但没有成功。
我正在使用以下代码:
private boolean verifySignature(String data, String signature) {
InputStream is = null;
try {
is = new ByteArrayInputStream(Config.getDogbarPublic().getBytes("UTF-8")); //Read DogBar Public key
BufferedReader br = new BufferedReader(new InputStreamReader(is));
List<String> lines = new ArrayList<String>();
String line;
while ((line = br.readLine()) != null)
lines.add(line);
// removes the first and last lines of the file (comments)
if (lines.size() > 1 && lines.get(0).startsWith("-----") && lines.get(lines.size() - 1).startsWith("-----")) {
lines.remove(0);
lines.remove(lines.size() - 1);
}
// concats the remaining lines to a single String
StringBuilder sb = new StringBuilder();
for (String aLine : lines)
sb.append(aLine);
String key = sb.toString();
byte[] keyBytes = Base64.decode(key.getBytes("utf-8"), Base64.DEFAULT);
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(spec);
Signature signCheck = Signature.getInstance("SHA1withRSA"); //Instantiate signature checker object.
signCheck.initVerify(publicKey);
signCheck.update(data.getBytes());
return signCheck.verify(signature.getBytes()); //verify signature with public key
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
谁能帮忙?我究竟做错了什么 ?
我错过了一些字节转换吗?也许 JSON 对象正在影响签名?
签名应该包含原始文件包含的 \n(换行符)还是 JSON 文件中不应该包含?
提前感谢所有帮助,非常感谢。
【问题讨论】:
-
我一直在尝试不同的方法,但没有成功,尝试从 JSON 对象中删除换行符,尝试 getBytes("ASCII") 和 getBytes("UTF-8")。
-
你有什么异常吗?哪一个?
-
我没有收到任何异常,它只是为
signCheck.verify()返回False
标签: java android json digital-signature