Digital Signature in java / android (RSA keys) -
i generate digital signature in java/android project private key(rsa) stored in db.
my 2 keys generated below code (project in production , cannot change it):
// keys pair (rsa) keypair rsakyepair = createkeypair(); // private/ public keys , store them in db string pri = getprivatekeybase64str(rsakyepair); string pub = getpublickeybase64str(rsakyepair)); public static keypair createkeypair() { keypair keypair = null; try { keypairgenerator keygen = keypairgenerator.getinstance("rsa"); keygen.initialize(key_length); keypair = keygen.generatekeypair(); } catch (nosuchalgorithmexception e) { e.printstacktrace(); return null; } return keypair; } public static string getprivatekeybase64str(keypair keypair){ if (keypair == null) return null; return getbase64strfrombyte(keypair.getprivate().getencoded()); } public static string getpublickeybase64str(keypair keypair){ if (keypair == null) return null; return getbase64strfrombyte(keypair.getpublic().getencoded()); } public static string getbase64strfrombyte(byte[] key){ if (key == null || key.length == 0) return null; return new string(base64.encode(key)); }
based on different sites (here , here), i'll try write code generate signature:
string mysignature = getdigitalsignature("my_string_", "my_private_string" ); /* * generated signed string * @param text : string sign * @param strprivatekey : private key (string format) */ public string getdigitalsignature(string text, string strprivatekey) { try { // private key string privatekey pk = loadprivatekey(strprivatekey); // text bytes byte[] data = text.getbytes("utf8"); // signature signature sig = signature.getinstance("md5withrsa"); sig.initsign(pk); sig.update(data); byte[] signaturebytes = sig.sign(); return javax.xml.bind.datatypeconverter.printbase64binary(signaturebytes); }catch(exception e){ return null; } } private privatekey loadprivatekey(string key64) throws generalsecurityexception { byte[] clear = base64.decode(key64, base64.default); pkcs8encodedkeyspec keyspec = new pkcs8encodedkeyspec(clear); keyfactory fact = keyfactory.getinstance("rsa"); privatekey priv = fact.generateprivate(keyspec); arrays.fill(clear, (byte) 0); return priv; }
for verify signature, use code in java api :
/* * verify signature of string * @param signature : signature * @param origina: original string verify * @param publickey: user public key */ public static boolean verfiysignature(string signature, string original, string publickey){ try{ // private key string publickey pk = loadpublickey(publickey); // text bytes byte[] originalbytes = original.getbytes("utf8"); //signature bytes //byte[] signaturebytes = signature.getbytes("utf8"); byte[] signaturebytes =javax.xml.bind.datatypeconverter.parsebase64binary(signature); signature sig = signature.getinstance("md5withrsa"); sig.initverify(pk); sig.update(originalbytes); return sig.verify(signaturebytes); }catch(exception e){ e.printstacktrace(); logger log = logger.getlogger(rsacipher.class); log.error("error signature:" + e.getmessage()); return false; } } /* * generate publickey object string * @ key64 : public key in string format (base 64) */ private static publickey loadpublickey(string key64) throws generalsecurityexception { byte[] data = javax.xml.bind.datatypeconverter.parsebase64binary(key64); x509encodedkeyspec spec = new x509encodedkeyspec(data); keyfactory fact = keyfactory.getinstance("rsa"); return fact.generatepublic(spec); }
i've run code real data, "verifysignature" returns "false".
i newbie in encryption world, forgive me dirty code.
--- edit
i got exception when verify method called:
java.security.signatureexception: signature encoding error
when signing returned signature base64-encoded:
return base64.encodetostring(signaturebytes, base64.default);
thus, when verifying have base64-decode signature string. is:
byte[] signaturebytes = signature.getbytes("utf8");
so signaturebytes
try verify different signaturebytes
had result of signing.
you sign using
signature sig = signature.getinstance("rsa");
but verify using
signature sig = signature.getinstance("md5withrsa");
obviously should use same algorithm in both cases.
Comments
Post a Comment