diff --git a/app/src/main/java/de/overview/wg/its/mispbump/MainActivity.java b/app/src/main/java/de/overview/wg/its/mispbump/MainActivity.java index 3388319..7519e6f 100644 --- a/app/src/main/java/de/overview/wg/its/mispbump/MainActivity.java +++ b/app/src/main/java/de/overview/wg/its/mispbump/MainActivity.java @@ -21,11 +21,13 @@ import android.view.View; import android.widget.CheckBox; import android.widget.TextView; import de.overview.wg.its.mispbump.adapter.SyncedPartnerAdapter; +import de.overview.wg.its.mispbump.auxiliary.AESSecurity; import de.overview.wg.its.mispbump.auxiliary.PreferenceManager; import de.overview.wg.its.mispbump.model.SyncedPartner; import de.overview.wg.its.mispbump.preferences.AppPreferenceActivity; import de.overview.wg.its.mispbump.preferences.AppPreferenceFragment; +import java.security.PublicKey; import java.util.ArrayList; import java.util.List; @@ -80,6 +82,29 @@ public class MainActivity extends AppCompatActivity { } + private void testAESSecurity() { + + String data = "This is the secret message"; + + AESSecurity aesA = AESSecurity.getInstance(); + AESSecurity aesB = AESSecurity.getInstance(); + + PublicKey pubA = aesA.getPublicKey(); + PublicKey pubB = aesB.getPublicKey(); + + aesA.setForeignPublicKey(pubB); + aesB.setForeignPublicKey(pubA); + + emptyPartnerListView.setText("ORIGINAL: " + data + "\n"); + + String encrypted = aesA.encrypt(data); + emptyPartnerListView.append("ENCRYPTED BY A: " + encrypted + "\n"); + + String decrypted = aesB.decrypt(encrypted); + emptyPartnerListView.append("DECRYPTED BY B: " + decrypted); + + } + private void initializeViews() { Toolbar toolbar = findViewById(R.id.toolbar); @@ -149,15 +174,8 @@ public class MainActivity extends AppCompatActivity { } private void refreshSyncedPartnerList() { -// syncedPartnerList = PreferenceManager.Instance(this).getSyncedPartnerList(); - - SyncedPartner sp = new SyncedPartner("Example Organisation 1", "https://www.organisationa1.de"); - sp.generateTimeStamp(); - syncedPartnerList.add(sp); - - sp = new SyncedPartner("Example Organisation 2", "https://www.organisation2.de"); - sp.generateTimeStamp(); - syncedPartnerList.add(sp); + // todo: uncomment + // syncedPartnerList = PreferenceManager.Instance(this).getSyncedPartnerList(); if (syncedPartnerList == null || syncedPartnerList.size() < 1) { emptyPartnerListView.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/de/overview/wg/its/mispbump/auxiliary/AESSecurity.java b/app/src/main/java/de/overview/wg/its/mispbump/auxiliary/AESSecurity.java index fb45975..44ebf56 100644 --- a/app/src/main/java/de/overview/wg/its/mispbump/auxiliary/AESSecurity.java +++ b/app/src/main/java/de/overview/wg/its/mispbump/auxiliary/AESSecurity.java @@ -1,40 +1,51 @@ package de.overview.wg.its.mispbump.auxiliary; import android.util.Base64; +import android.util.Log; import javax.crypto.*; +import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.*; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; +import java.util.Arrays; public class AESSecurity { private static final String TAG = "MISP_LOGGING"; - private static final String ALGORITHM = "AES"; - private static AESSecurity instance; + private static final String ENCRYPT_ALGORITHM = "AES/CBC/PKCS5Padding"; + private static final String KEY_PAIR_ALGORITHM = "EC"; + private static final int KEY_SIZE = 521; // 224 | 256 | 384 | 521 + private static final String KEY_AGREEMENT_ALGORITHM = "ECDH"; + + private static AESSecurity instance; private PublicKey publickey; private KeyAgreement keyAgreement; + private byte[] sharedSecret; + private IvParameterSpec ivParameterSpec; private AESSecurity() { initialize(); } + /*** + * Generates a public and a private key using an elliptic curve algorithm (256 bit) + * The private key is fed into the key agreement instance + */ private void initialize() { - KeyPairGenerator kpg = null; try { - kpg = KeyPairGenerator.getInstance("EC"); - kpg.initialize(256); + KeyPairGenerator kpg = KeyPairGenerator.getInstance(KEY_PAIR_ALGORITHM); + kpg.initialize(KEY_SIZE); KeyPair kp = kpg.generateKeyPair(); - publickey = kp.getPublic(); - keyAgreement = KeyAgreement.getInstance("ECDH"); + keyAgreement = KeyAgreement.getInstance(KEY_AGREEMENT_ALGORITHM); keyAgreement.init(kp.getPrivate()); } catch (NoSuchAlgorithmException | InvalidKeyException e) { @@ -42,23 +53,42 @@ public class AESSecurity { } } + /*** + * Generates a shared secret with a given public key + * @param publickey + */ public void setForeignPublicKey(PublicKey publickey) { - try { + + try { + keyAgreement.doPhase(publickey, true); - sharedSecret = keyAgreement.generateSecret(); - } catch (InvalidKeyException e) { + + byte[] tmpSharedSecret = keyAgreement.generateSecret(); + + sharedSecret = Arrays.copyOfRange(tmpSharedSecret, 0, 32); + + byte[] inputVector = Arrays.copyOfRange(sharedSecret, 32, 48); + + ivParameterSpec = new IvParameterSpec(inputVector); + + } catch (InvalidKeyException e) { e.printStackTrace(); } } public String encrypt(String data) { try { + Key key = generateKey(); - Cipher c = Cipher.getInstance(ALGORITHM); - c.init(Cipher.ENCRYPT_MODE, key); + Cipher c = Cipher.getInstance(ENCRYPT_ALGORITHM); - byte[] encVal = c.doFinal(data.getBytes()); + try { + c.init(Cipher.ENCRYPT_MODE, key, ivParameterSpec); + } catch (InvalidAlgorithmParameterException e) { + e.printStackTrace(); + } + byte[] encVal = c.doFinal(data.getBytes()); return Base64.encodeToString(encVal, 0); } catch (BadPaddingException | InvalidKeyException | NoSuchPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException e) { @@ -70,10 +100,16 @@ public class AESSecurity { public String decrypt(String data) { try { Key key = generateKey(); - Cipher c = Cipher.getInstance(ALGORITHM); - c.init(Cipher.DECRYPT_MODE, key); - byte[] decoded = Base64.decode(data, 0); + Cipher c = Cipher.getInstance(ENCRYPT_ALGORITHM); + + try { + c.init(Cipher.DECRYPT_MODE, key, ivParameterSpec); + } catch (InvalidAlgorithmParameterException e) { + e.printStackTrace(); + } + + byte[] decoded = Base64.decode(data, 0); byte[] decValue = c.doFinal(decoded); return new String(decValue); } catch (BadPaddingException | InvalidKeyException | NoSuchPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException e) { @@ -87,21 +123,22 @@ public class AESSecurity { } private Key generateKey() { - return new SecretKeySpec(sharedSecret, ALGORITHM); + + return new SecretKeySpec(sharedSecret, ENCRYPT_ALGORITHM); + } public static String publicKeyToString(PublicKey key) { return Base64.encodeToString(key.getEncoded(), Base64.DEFAULT); } + public static PublicKey publicKeyFromString(String key) { - KeyFactory kf = null; + try { - byte[] input = Base64.decode(key, Base64.DEFAULT); + byte[] input = Base64.decode(key, Base64.DEFAULT); + return KeyFactory.getInstance("EC").generatePublic(new X509EncodedKeySpec(input)); - try { - kf = KeyFactory.getInstance("EC"); // normal: DH - return kf.generatePublic(new X509EncodedKeySpec(input)); } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { e.printStackTrace(); } @@ -110,10 +147,15 @@ public class AESSecurity { } public static AESSecurity getInstance() { - if(instance == null) { - instance = new AESSecurity(); - } - return instance; + //todo: make singleton again + +// if(instance == null) { +// instance = new AESSecurity(); +// } +// +// return instance; + + return new AESSecurity(); } } \ No newline at end of file diff --git a/screenshots/MispBump-poster-10.pdf b/screenshots/MispBump-poster-10.pdf new file mode 100644 index 0000000..c3359c9 Binary files /dev/null and b/screenshots/MispBump-poster-10.pdf differ diff --git a/screenshots/sync_si_received.png b/screenshots/sync_si_received.png new file mode 100644 index 0000000..d6178e7 Binary files /dev/null and b/screenshots/sync_si_received.png differ