From 7efcf90df4f78abe0a5b10df69d849fbb15a2273 Mon Sep 17 00:00:00 2001 From: "bessani@gmail.com" Date: Tue, 17 May 2011 19:24:17 +0000 Subject: [PATCH] Safely paralelizes signature verification from different clients to exploit multicore machines. --- .../smart/clientsmanagement/ClientData.java | 40 ++++++--- .../clientsmanagement/ClientsManager.java | 10 ++- src/navigators/smart/tom/core/TOMLayer.java | 6 +- .../smart/tom/util/SignatureTest.java | 86 +++++++++++++++++++ src/navigators/smart/tom/util/TOMUtil.java | 51 +++++++---- 5 files changed, 158 insertions(+), 35 deletions(-) create mode 100644 src/navigators/smart/tom/util/SignatureTest.java diff --git a/src/navigators/smart/clientsmanagement/ClientData.java b/src/navigators/smart/clientsmanagement/ClientData.java index 25da6741..73415dbf 100644 --- a/src/navigators/smart/clientsmanagement/ClientData.java +++ b/src/navigators/smart/clientsmanagement/ClientData.java @@ -18,11 +18,14 @@ package navigators.smart.clientsmanagement; +import java.security.PublicKey; +import java.security.Signature; +import java.security.SignatureException; import java.util.Iterator; import java.util.concurrent.locks.ReentrantLock; -import navigators.smart.reconfiguration.ReconfigurationManager; import navigators.smart.tom.core.messages.TOMMessage; +import navigators.smart.tom.util.Logger; import navigators.smart.tom.util.TOMUtil; public class ClientData { @@ -43,15 +46,26 @@ public class ClientData { private TOMMessage lastReplySent = null; - private ReconfigurationManager manager; + private Signature signatureVerificator = null; + /** - * Class constructor. Just store the clientId. + * Class constructor. Just store the clientId and creates a signature + * verificator for a given client public key. * - * @param clientId + * @param clientId client unique id + * @param publicKey client public key */ - public ClientData(int clientId, ReconfigurationManager manager) { + public ClientData(int clientId, PublicKey publicKey) { this.clientId = clientId; - this.manager = manager; + if(publicKey != null) { + try { + signatureVerificator = Signature.getInstance("SHA1withRSA"); + signatureVerificator.initVerify(publicKey); + Logger.println("Signature verifier initialized for client "+clientId); + } catch (Exception ex) { + ex.printStackTrace(); + } + } } public int getClientId() { @@ -79,12 +93,14 @@ public class ClientData { }*/ public boolean verifySignature(byte[] message, byte[] signature) { - //******* EDUARDO BEGIN **************// - - return TOMUtil.verifySignature(manager.getStaticConf().getRSAPublicKey(clientId), - message, signature); - - //******* EDUARDO END **************// + if(signatureVerificator != null) { + try { + return TOMUtil.verifySignature(signatureVerificator, message, signature); + } catch (SignatureException ex) { + ex.printStackTrace(); + } + } + return false; } public void setLastMessageExecuted(int lastMessageExecuted) { diff --git a/src/navigators/smart/clientsmanagement/ClientsManager.java b/src/navigators/smart/clientsmanagement/ClientsManager.java index aa9de244..f2c6d138 100644 --- a/src/navigators/smart/clientsmanagement/ClientsManager.java +++ b/src/navigators/smart/clientsmanagement/ClientsManager.java @@ -64,9 +64,13 @@ public class ClientsManager { if (clientData == null) { Logger.println("(ClientsManager.getClientData) Creating new client data, client id="+clientId); - //******* EDUARDO BEGIN **************// - clientData = new ClientData(clientId,manager); - //******* EDUARDO END **************// + + //******* EDUARDO BEGIN **************// + clientData = new ClientData(clientId, + (manager.getStaticConf().getUseSignatures() == 1)? + manager.getStaticConf().getRSAPublicKey(clientId): + null); + //******* EDUARDO END **************// clientsData.put(clientId, clientData); } diff --git a/src/navigators/smart/tom/core/TOMLayer.java b/src/navigators/smart/tom/core/TOMLayer.java index acdba1ca..a6b24269 100644 --- a/src/navigators/smart/tom/core/TOMLayer.java +++ b/src/navigators/smart/tom/core/TOMLayer.java @@ -63,7 +63,6 @@ import navigators.smart.tom.core.timer.messages.RTMessage; import navigators.smart.tom.util.BatchBuilder; import navigators.smart.tom.util.BatchReader; import navigators.smart.tom.util.Logger; -import navigators.smart.tom.util.Storage; import navigators.smart.tom.util.TOMUtil; @@ -356,7 +355,7 @@ public final class TOMLayer extends Thread implements RequestReceiver { // return the batch return bb.createBatch(System.currentTimeMillis(), numberOfNonces, numberOfMessages, totalMessageSize, this.reconfManager.getStaticConf().getUseSignatures() == 1, messages, signatures,this.reconfManager); - } + } @@ -510,9 +509,8 @@ public final class TOMLayer extends Thread implements RequestReceiver { * @return */ public TOMMessage[] checkProposedValue(byte[] proposedValue) { - if (Logger.debug) { Logger.println("(TOMLayer.isProposedValueValid) starting"); - } + BatchReader batchReader = new BatchReader(proposedValue, this.reconfManager.getStaticConf().getUseSignatures() == 1); diff --git a/src/navigators/smart/tom/util/SignatureTest.java b/src/navigators/smart/tom/util/SignatureTest.java new file mode 100644 index 00000000..3b71afe4 --- /dev/null +++ b/src/navigators/smart/tom/util/SignatureTest.java @@ -0,0 +1,86 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package navigators.smart.tom.util; + +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Signature; + +/** + * + * @author alysson + */ +public class SignatureTest { + + public static void main(String[] args) throws Exception { + byte[] data = new byte[20]; + byte[] signature; + Signature signEng; + long start, end; + + KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); + kpg.initialize(1024); + KeyPair kp = kpg.genKeyPair(); + PublicKey publicKey = kp.getPublic(); + PrivateKey privateKey = kp.getPrivate(); + + signEng = Signature.getInstance("SHA1withRSA"); + + for(int i=0; i<1000; i++) { + signEng = Signature.getInstance("SHA1withRSA"); + signEng.initSign(privateKey); + } + start = System.currentTimeMillis(); + for(int i=0; i<1000; i++) { + signEng = Signature.getInstance("SHA1withRSA"); + signEng.initSign(privateKey); + } + end = System.currentTimeMillis(); + System.out.println("1000 init sign: "+(end-start)+"ms"); + + for(int i=0; i<1000; i++) { + signEng.update(data); + signature = signEng.sign(); + } + start = System.currentTimeMillis(); + for(int i=0; i<1000; i++) { + signEng.update(data); + signature = signEng.sign(); + } + end = System.currentTimeMillis(); + System.out.println("1000 sign: "+(end-start)+"ms"); + + signEng.update(data); + signature = signEng.sign(); + + for(int i=0; i<1000; i++) { + signEng = Signature.getInstance("SHA1withRSA"); + signEng.initVerify(publicKey); + } + start = System.currentTimeMillis(); + for(int i=0; i<1000; i++) { + signEng = Signature.getInstance("SHA1withRSA"); + signEng.initVerify(publicKey); + } + end = System.currentTimeMillis(); + System.out.println("1000 init verify: "+(end-start)+"ms"); + + for(int i=0; i<1000; i++) { + signEng.update(data); + signEng.verify(signature); + } + start = System.currentTimeMillis(); + for(int i=0; i<1000; i++) { + signEng.update(data); + signEng.verify(signature); + } + end = System.currentTimeMillis(); + System.out.println("1000 verify: "+(end-start)+"ms"); + } + +} diff --git a/src/navigators/smart/tom/util/TOMUtil.java b/src/navigators/smart/tom/util/TOMUtil.java index 3cb53d14..fab2c09c 100644 --- a/src/navigators/smart/tom/util/TOMUtil.java +++ b/src/navigators/smart/tom/util/TOMUtil.java @@ -25,7 +25,9 @@ import java.io.ObjectOutputStream; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; +import java.security.SignatureException; import java.util.Arrays; +import java.util.concurrent.Semaphore; import java.util.concurrent.locks.ReentrantLock; import navigators.smart.reconfiguration.ViewManager; @@ -80,13 +82,16 @@ public class TOMUtil { } catch (IOException ex) { ex.printStackTrace(); + return null; } return bOut.toByteArray(); } public static Object getObject(byte[] b) { - if (b == null) System.out.println("O ARRAY E NULL!!!!"); + if (b == null) + return null; + ByteArrayInputStream bInp = new ByteArrayInputStream(b); try { ObjectInputStream obInp = new ObjectInputStream(bInp); @@ -95,7 +100,6 @@ public class TOMUtil { bInp.close(); return ret; } catch (Exception ex) { - System.out.println("Isto rebenta aqui!!"); ex.printStackTrace(); return null; } @@ -111,6 +115,7 @@ public class TOMUtil { */ public static byte[] signMessage(PrivateKey key, byte[] message) { lock.lock(); + byte[] result = null; try { if (signatureEngine == null) { signatureEngine = Signature.getInstance("SHA1withRSA"); @@ -120,14 +125,13 @@ public class TOMUtil { signatureEngine.update(message); - byte[] result = signatureEngine.sign(); - lock.unlock(); - return result; + result = signatureEngine.sign(); } catch (Exception e) { - lock.unlock(); e.printStackTrace(); - return null; } + + lock.unlock(); + return result; } /** @@ -136,10 +140,11 @@ public class TOMUtil { * @param key the public key to be used to verify the signature * @param message the signed message * @param signature the signature to be verified - * @return the signature + * @return true if the signature is valid, false otherwise */ public static boolean verifySignature(PublicKey key, byte[] message, byte[] signature) { lock.lock(); + boolean result = false; //long startTime = System.nanoTime(); try { if (signatureEngine == null) { @@ -148,9 +153,7 @@ public class TOMUtil { signatureEngine.initVerify(key); - signatureEngine.update(message); - - boolean result = signatureEngine.verify(signature); + result = verifySignature(signatureEngine, message, signature); /* st.store(System.nanoTime()-startTime); //statistics about signature execution time @@ -166,14 +169,30 @@ public class TOMUtil { count = 0; st = new Storage(BENCHMARK_PERIOD); } - */ - lock.unlock(); - return result; + */ } catch (Exception e) { - lock.unlock(); e.printStackTrace(); - return false; } + + lock.unlock(); + return result; + } + + /** + * Verify the signature of a message. + * + * @param initializedSignatureEngine a signature engine already initialized + * for verification + * @param message the signed message + * @param signature the signature to be verified + * @return true if the signature is valid, false otherwise + */ + public static boolean verifySignature(Signature initializedSignatureEngine, byte[] message, byte[] signature) throws SignatureException { + //TODO: limit the amount of parallelization we can do to save some cores for other tasks + //maybe we can use a semaphore here initialized with the maximum number of parallel verifications: + //Semaphore sem = new Semaphore(10, true); then we can run sem.acquire() and sem.release() + initializedSignatureEngine.update(message); + return initializedSignatureEngine.verify(signature); } public static String byteArrayToString(byte[] b) { -- GitLab