Sto sviluppando un'applicazione Android che richiede la firma digitale di un documento html. Il documento risiede nel DB, in un modulo JSON. Sto firmando il documento localmente utilizzando uno script bash che ho trovato su qualche domanda altro SO:Verifica firma digitale su Android
openssl dgst -sha1 someHTMLDoc.html > hash openssl rsautl -sign -inkey privateKey.pem -keyform PEM -in hash > signature.bin
chiave privata è stata generata utilizzando:
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:3 -out privateKey.pem
chiave pubblica è stata generata utilizzando:
openssl pkey -in privateKey.pem -out publicKey.pem -pubout
Voglio verificare la firma creata in Signature.bin insieme con i dati in alcuniHTMLDoc.html, indietro in th e applicazione.
io mando sia il codice HTML e la firma come JSON oggetto es:
{ "data" : "<html><body></body></html>", "signature":"6598 13a9 b12b 21a9 ..... " }
L'applicazione Android detiene il PublicKey in preferenze condivise come segue:
-----BEGIN PUBLIC KEY----- MIIBIDANBgkqhkiG9w0AAAEFAAOCAQ0AvniCAKCAQEAvni/NSEX3Rhx91HkJl85 \nx1noyYET ......
Avviso del "\ n" (newline) (è stato aggiunto automaticamente durante la copia di stringa da publicKey.pem a Android Gradle Config.
Ok, dopo tutti i preparativi, ora la domanda. Sto provando a convalidare la chiave senza successo.
Sto usando il seguente codice:
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;
}
}
chiunque può aiutare? Che cosa sto facendo di sbagliato ?
Mi manca qualche conversione di byte? forse l'oggetto JSON sta influenzando la firma?
Se una firma contiene lo \ n (interruzione di riga) che il file originale contiene o dovrebbe essere senza nel file JSON?
Grazie in anticipo per tutto l'aiuto, è molto apprezzato.
Continuo a provare diversi metodi senza esito positivo, ho provato a rimuovere le interruzioni di riga dall'oggetto JSON, ho provato getBytes ("ASCII") e getBytes ("UTF-8"). – Noxymon
Hai ricevuto qualche eccezione? Quale? – Henry
non ho ricevuto alcuna eccezione, restituisce solo False per 'signCheck.verify()' – Noxymon