Skip to content

Commit ceeab0c

Browse files
committed
made adaptions for my programming class next semester.
1 parent b404d4f commit ceeab0c

File tree

2 files changed

+117
-1
lines changed

2 files changed

+117
-1
lines changed

src/net/sharksystem/crypto/BasicCryptoKeyStorage.java

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55

66
import javax.crypto.KeyGenerator;
77
import javax.crypto.SecretKey;
8+
import java.io.*;
89
import java.security.*;
10+
import java.security.spec.InvalidKeySpecException;
11+
import java.security.spec.X509EncodedKeySpec;
912
import java.util.HashMap;
1013

1114
public class BasicCryptoKeyStorage implements BasicCryptoParameters {
@@ -20,8 +23,11 @@ public class BasicCryptoKeyStorage implements BasicCryptoParameters {
2023
public static int DEFAULT_AES_KEY_SIZE = 128; // TODO we can do better
2124
public static final String DEFAULT_SIGNATURE_ALGORITHM = "SHA256withRSA";
2225

26+
// for debugging only - we don't have private key in real apps
2327
private HashMap<String, KeyPair> peerKeyPairs = new HashMap<>();
2428

29+
private HashMap<CharSequence, PublicKey> peerPublicKeys = new HashMap<CharSequence, PublicKey>();
30+
2531
public BasicCryptoKeyStorage(String ownerID) throws ASAPSecurityException {
2632
// generate owners key pair;
2733
this.ownerID = ownerID;
@@ -95,11 +101,24 @@ public PublicKey getPublicKey() throws ASAPSecurityException {
95101
@Override
96102
public PublicKey getPublicKey(CharSequence subjectID) throws ASAPSecurityException {
97103
KeyPair keyPair = this.peerKeyPairs.get(subjectID);
98-
if(keyPair == null) throw new ASAPSecurityException("no key pair for " + subjectID);
104+
if(keyPair == null) {
105+
// try there - which is more likely
106+
PublicKey publicKey = this.peerPublicKeys.get(subjectID);
107+
if(publicKey != null) {
108+
// got it
109+
return publicKey;
110+
}
111+
// else
112+
throw new ASAPSecurityException("no key pair for " + subjectID);
113+
}
99114

100115
return keyPair.getPublic();
101116
}
102117

118+
void putPublicKey(CharSequence peer, PublicKey key) {
119+
this.peerPublicKeys.put(peer, key);
120+
}
121+
103122
/**
104123
* In reality there cannot be such a method - but we are in a test.
105124
* @param subjectID
@@ -142,4 +161,59 @@ public void addKeyPair(String peerID, KeyPair keyPair) {
142161

143162
this.peerKeyPairs.put(peerID, keyPair);
144163
}
164+
165+
/**
166+
* Write storage owners' public key to stream
167+
* @param os
168+
*/
169+
public void writePublicKey(OutputStream os) throws ASAPSecurityException, IOException {
170+
PublicKey publicKey = this.getPublicKey();
171+
172+
String format = publicKey.getFormat();
173+
String algorithm = publicKey.getAlgorithm();
174+
byte[] byteEncodedPublicKey = publicKey.getEncoded();
175+
int length = byteEncodedPublicKey.length;
176+
177+
// makes it much easier to serialize simple data
178+
DataOutputStream dos = new DataOutputStream(os);
179+
180+
// write to stream
181+
dos.writeUTF(format);
182+
dos.writeUTF(algorithm);
183+
dos.writeInt(byteEncodedPublicKey.length);
184+
185+
// write encoded key directly on stream
186+
os.write(byteEncodedPublicKey);
187+
}
188+
189+
/**
190+
* Read public key from another peer from an extern source (input stream)
191+
* @param peer
192+
* @param is
193+
*/
194+
public void readPublicKey(CharSequence peer, InputStream is) throws ASAPSecurityException, IOException, NoSuchAlgorithmException, InvalidKeySpecException {
195+
DataInputStream dis = new DataInputStream(is);
196+
197+
// read in same order as written
198+
String format = dis.readUTF();
199+
String algorithm = dis.readUTF();
200+
int len = dis.readInt();
201+
202+
// allocate memory
203+
byte[] byteEncodedPublicKey = new byte[len];
204+
205+
// read encoded key directly from stream
206+
is.read(byteEncodedPublicKey);
207+
208+
// create key object
209+
210+
// should be revised - why?
211+
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(byteEncodedPublicKey);
212+
213+
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
214+
PublicKey publicKey = keyFactory.generatePublic(pubKeySpec);
215+
216+
// store it
217+
this.putPublicKey(peer, publicKey);
218+
}
145219
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package net.sharksystem.asap;
2+
3+
import net.sharksystem.crypto.ASAPCryptoAlgorithms;
4+
import net.sharksystem.crypto.BasicCryptoKeyStorage;
5+
import org.junit.Assert;
6+
import org.junit.Test;
7+
8+
import java.io.ByteArrayInputStream;
9+
import java.io.ByteArrayOutputStream;
10+
import java.io.IOException;
11+
import java.security.NoSuchAlgorithmException;
12+
import java.security.spec.InvalidKeySpecException;
13+
14+
public class BasisCryptoTests {
15+
public static final String ALICE_ID = "Alice";
16+
public static final String BOB_ID = "Bob";
17+
18+
@Test
19+
public void publicKeyExportImport() throws ASAPSecurityException, IOException, InvalidKeySpecException, NoSuchAlgorithmException {
20+
BasicCryptoKeyStorage aliceStorage = new BasicCryptoKeyStorage(ALICE_ID);
21+
// a message
22+
String msg = "Hi Bob";
23+
24+
// convert to bytes
25+
byte[] msgBytes = msg.getBytes();
26+
27+
// sign a message - with Alice' private key
28+
byte[] signatureBytes = ASAPCryptoAlgorithms.sign(msgBytes, aliceStorage);
29+
30+
// Alice could now send message with signature to bob - we are in a test, nothing to do here.
31+
32+
// Bob need to know Alice' public key to verify - simulate transfer
33+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
34+
aliceStorage.writePublicKey(baos);
35+
36+
BasicCryptoKeyStorage bobStorage = new BasicCryptoKeyStorage(BOB_ID);
37+
// store Alice' public key with Bob
38+
bobStorage.readPublicKey(ALICE_ID, new ByteArrayInputStream(baos.toByteArray()));
39+
40+
Assert.assertTrue(ASAPCryptoAlgorithms.verify(msgBytes, signatureBytes, ALICE_ID, bobStorage));
41+
}
42+
}

0 commit comments

Comments
 (0)