Making PublicKey class throw exception when passed private key data

This commit is contained in:
Nelson R. Perez 2016-12-12 13:13:39 -05:00
parent d6783fd9f3
commit 15ddcd86cd
5 changed files with 86 additions and 37 deletions

View file

@ -56,8 +56,8 @@ public class Main {
// test.testAccountUpdateOperationBroadcast(); // test.testAccountUpdateOperationBroadcast();
// test.testCreateBinFile(); // test.testCreateBinFile();
// test.testImportBinFile(); // test.testImportBinFile();
test.testLookupAccounts(); // test.testLookupAccounts();
// test.testLookupAccounts(); // test.testLookupAccounts();
// test.testDecodeMemo(); test.testDecodeMemo();
} }
} }

View file

@ -2,6 +2,7 @@ package de.bitsharesmunich.graphenej;
import de.bitsharesmunich.graphenej.interfaces.ByteSerializable; import de.bitsharesmunich.graphenej.interfaces.ByteSerializable;
import org.bitcoinj.core.ECKey; import org.bitcoinj.core.ECKey;
import org.spongycastle.math.ec.ECPoint;
/** /**
* Created by nelson on 11/30/16. * Created by nelson on 11/30/16.
@ -10,6 +11,9 @@ public class PublicKey implements ByteSerializable {
private ECKey publicKey; private ECKey publicKey;
public PublicKey(ECKey key) { public PublicKey(ECKey key) {
if(key.hasPrivKey()){
throw new IllegalStateException("Passing a private key to PublicKey constructor");
}
this.publicKey = key; this.publicKey = key;
} }
@ -19,10 +23,20 @@ public class PublicKey implements ByteSerializable {
@Override @Override
public byte[] toBytes() { public byte[] toBytes() {
return publicKey.getPubKey(); if(publicKey.isCompressed()) {
return publicKey.getPubKey();
}else{
publicKey = ECKey.fromPublicOnly(ECKey.compressPoint(publicKey.getPubKeyPoint()));
return publicKey.getPubKey();
}
} }
public String getAddress(){ public String getAddress(){
return new Address(publicKey).toString(); ECKey pk = ECKey.fromPublicOnly(publicKey.getPubKey());
if(!pk.isCompressed()){
ECPoint point = ECKey.compressPoint(pk.getPubKeyPoint());
pk = ECKey.fromPublicOnly(point);
}
return new Address(pk).toString();
} }
} }

View file

@ -299,7 +299,7 @@ public class Test {
try { try {
// Creating memo // Creating memo
PublicKey from = new PublicKey(new BrainKey(Main.BILTHON_83_BRAIN_KEY, 0).getPrivateKey()); ECKey from = new BrainKey(Main.BILTHON_83_BRAIN_KEY, 0).getPrivateKey();
PublicKey to = new PublicKey(ECKey.fromPublicOnly(new BrainKey(Main.BILTHON_5_BRAIN_KEY, 0).getPublicKey())); PublicKey to = new PublicKey(ECKey.fromPublicOnly(new BrainKey(Main.BILTHON_5_BRAIN_KEY, 0).getPublicKey()));
Memo memo = new MemoBuilder().setFromKey(from).setToKey(to).setMessage("sample message").build(); Memo memo = new MemoBuilder().setFromKey(from).setToKey(to).setMessage("sample message").build();
@ -377,15 +377,44 @@ public class Test {
} }
public void testGetAccountByName() { public void testGetAccountByName() {
WitnessResponseListener accountByNameListener = new WitnessResponseListener() {
@Override
public void onSuccess(WitnessResponse response) {
System.out.println("onSuccess");
WitnessResponse<AccountProperties> accountProperties = response;
System.out.println("account id: "+accountProperties.result.id);
Authority authority = accountProperties.result.active;
System.out.println("number of keys: "+authority.getKeyAuths().size());
for(PublicKey publicKey : authority.getKeyAuths()){
System.out.println("public key: "+publicKey.getAddress());
}
}
@Override
public void onError(BaseResponse.Error error) {
System.out.println("onError. Msg: "+error.message);
}
};
try { try {
WebSocketFactory factory = new WebSocketFactory().setConnectionTimeout(5000); SSLContext context = null;
WebSocket mWebSocket = factory.createSocket(WITNESS_URL); context = NaiveSSLContext.getInstance("TLS");
mWebSocket.addListener(new GetAccountByName("bilthon-83", mListener)); WebSocketFactory factory = new WebSocketFactory();
// Set the custom SSL context.
factory.setSSLContext(context);
WebSocket mWebSocket = factory.createSocket(BLOCK_PAY_DE);
mWebSocket.addListener(new GetAccountByName("bilthon-83", accountByNameListener));
mWebSocket.connect(); mWebSocket.connect();
} catch (IOException e) { } catch (IOException e) {
System.out.println("IOException. Msg: " + e.getMessage()); System.out.println("IOException. Msg: " + e.getMessage());
} catch (WebSocketException e) { } catch (WebSocketException e) {
System.out.println("WebSocketException. Msg: " + e.getMessage()); System.out.println("WebSocketException. Msg: " + e.getMessage());
} catch (NoSuchAlgorithmException e) {
System.out.println("NoSuchAlgorithmException. Msg: "+e.getMessage());
} }
} }
@ -434,7 +463,7 @@ public class Test {
} else { } else {
System.out.println("Using brain key: " + Main.BILTHON_5_BRAIN_KEY); System.out.println("Using brain key: " + Main.BILTHON_5_BRAIN_KEY);
// brainKey = new BrainKey(Main.BILTHON_83_BRAIN_KEY, 0); // brainKey = new BrainKey(Main.BILTHON_83_BRAIN_KEY, 0);
brainKey = new BrainKey("CYNEBOT LUFBERY DAUNTER TOO SALOOP HOPOFF DIAULOS REV AES TORPOR RECTRIX DEVILRY", 0); brainKey = new BrainKey("CONCOCT BALOW JINJILI UNOILED MESOBAR REEST BREATH OOCYST MOUSLE HOGWARD STOLLEN ASH", 0);
} }
ECKey key = brainKey.getPrivateKey(); ECKey key = brainKey.getPrivateKey();
System.out.println("Private key..................: " + Util.bytesToHex(key.getSecretBytes())); System.out.println("Private key..................: " + Util.bytesToHex(key.getSecretBytes()));
@ -707,13 +736,13 @@ public class Test {
public void testDecodeMemo() { public void testDecodeMemo() {
PublicKey from = new PublicKey((new BrainKey(Main.BILTHON_83_BRAIN_KEY, 0).getPrivateKey())); ECKey from = new BrainKey(Main.BILTHON_83_BRAIN_KEY, 0).getPrivateKey();
PublicKey to = new PublicKey(new BrainKey(Main.BILTHON_5_BRAIN_KEY, 0).getPrivateKey()); PublicKey to = new PublicKey(ECKey.fromPublicOnly(new BrainKey(Main.BILTHON_5_BRAIN_KEY, 0).getPublicKey()));
Memo sendMemo = new MemoBuilder().setFromKey(from).setToKey(to).setMessage("test message").build(); Memo sendMemo = new MemoBuilder().setFromKey(from).setToKey(to).setMessage("test message").build();
JsonElement memoJson = sendMemo.toJsonObject(); JsonElement memoJson = sendMemo.toJsonObject();
System.out.println("generated Json : " + memoJson.toString()); System.out.println("generated Json : " + memoJson.toString());
System.out.println("Decode Memo : " + Memo.decodeMessage(from, to, memoJson.getAsJsonObject().get("message").getAsString(), memoJson.getAsJsonObject().get("nonce").getAsString())); // System.out.println("Decode Memo : " + Memo.decodeMessage(from, to, memoJson.getAsJsonObject().get("message").getAsString(), memoJson.getAsJsonObject().get("nonce").getAsString()));
} }
} }

View file

@ -8,6 +8,8 @@ import de.bitsharesmunich.graphenej.Util;
import de.bitsharesmunich.graphenej.crypto.SecureRandomStrengthener; import de.bitsharesmunich.graphenej.crypto.SecureRandomStrengthener;
import de.bitsharesmunich.graphenej.interfaces.ByteSerializable; import de.bitsharesmunich.graphenej.interfaces.ByteSerializable;
import de.bitsharesmunich.graphenej.interfaces.JsonSerializable; import de.bitsharesmunich.graphenej.interfaces.JsonSerializable;
import org.bitcoinj.core.ECKey;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
@ -17,13 +19,13 @@ import java.security.SecureRandom;
* Created by nelson on 11/9/16. * Created by nelson on 11/9/16.
*/ */
public class Memo implements ByteSerializable, JsonSerializable { public class Memo implements ByteSerializable, JsonSerializable {
public final static String TAG = "Memo";
public static final String KEY_FROM = "from"; public static final String KEY_FROM = "from";
public static final String KEY_TO = "to"; public static final String KEY_TO = "to";
public static final String KEY_NONCE = "nonce"; public static final String KEY_NONCE = "nonce";
public static final String KEY_MESSAGE = "message"; public static final String KEY_MESSAGE = "message";
private PublicKey from; private ECKey from;
private PublicKey to; private PublicKey to;
private final byte[] nonce = new byte[8]; private final byte[] nonce = new byte[8];
private byte[] message; private byte[] message;
@ -36,7 +38,7 @@ public class Memo implements ByteSerializable, JsonSerializable {
this.to = null; this.to = null;
this.message = null; this.message = null;
} }
/** /**
* Implement metod, serialized this Object * Implement metod, serialized this Object
* @return the byte array of this object serialized * @return the byte array of this object serialized
@ -50,7 +52,10 @@ public class Memo implements ByteSerializable, JsonSerializable {
for (int i = 0; i < nonceformat.length; i++) { for (int i = 0; i < nonceformat.length; i++) {
nonceformat[i] = nonce[nonce.length - i - 1]; nonceformat[i] = nonce[nonce.length - i - 1];
} }
return Bytes.concat(new byte[]{1}, this.from.toBytes(), this.to.toBytes(), nonceformat, new byte[]{(byte) this.message.length}, this.message); org.spongycastle.math.ec.ECPoint point = ECKey.compressPoint(from.getPubKeyPoint());
PublicKey senderPublicKey = new PublicKey(ECKey.fromPublicOnly(point));
return Bytes.concat(new byte[]{1}, senderPublicKey.toBytes(), this.to.toBytes(), nonceformat, new byte[]{(byte) this.message.length}, this.message);
} }
} }
@ -61,20 +66,20 @@ public class Memo implements ByteSerializable, JsonSerializable {
* @param msg The message in bytes * @param msg The message in bytes
* @return a Memo corresponding with the message encoding * @return a Memo corresponding with the message encoding
*/ */
public static Memo encodeMessage(PublicKey fromKey, PublicKey toKey, byte[] msg) { public static Memo encodeMessage(ECKey fromKey, PublicKey toKey, byte[] msg) {
return encodeMessage(fromKey, toKey, msg, 0); return encodeMessage(fromKey, toKey, msg, 0);
} }
/** /**
* Encode a message a return a memo with that message encoded * Encode a message a return a memo with that message encoded
* *
* @param fromKey The source destination, need to have a private key accesss * @param fromKey The source destination, need to have a private key accesss
* @param toKey The destination, needs only the public key access * @param toKey The destination, needs only the public key access
* @param msg The message in bytes * @param msg The message in bytes
* @param custom_nonce the custom nonce to be use or 0 to create a new one * @param custom_nonce the custom nonce to be use or 0 to create a new one
* @return a Memo corresponding with the message encoding * @return a Memo corresponding with the message encoding
*/ */
public static Memo encodeMessage(PublicKey fromKey, PublicKey toKey, byte[] msg, long custom_nonce) { public static Memo encodeMessage(ECKey fromKey, PublicKey toKey, byte[] msg, long custom_nonce) {
Memo memo = new Memo(); Memo memo = new Memo();
try { try {
MessageDigest md = MessageDigest.getInstance("SHA-256"); MessageDigest md = MessageDigest.getInstance("SHA-256");
@ -84,7 +89,7 @@ public class Memo implements ByteSerializable, JsonSerializable {
if (custom_nonce == 0) { if (custom_nonce == 0) {
SecureRandomStrengthener randomStrengthener = SecureRandomStrengthener.getInstance(); SecureRandomStrengthener randomStrengthener = SecureRandomStrengthener.getInstance();
//randomStrengthener.addEntropySource(new AndroidRandomSource()); // randomStrengthener.addEntropySource(new AndroidRandomSource());
SecureRandom secureRandom = randomStrengthener.generateAndSeedRandomNumberGenerator(); SecureRandom secureRandom = randomStrengthener.generateAndSeedRandomNumberGenerator();
secureRandom.nextBytes(memo.nonce); secureRandom.nextBytes(memo.nonce);
@ -100,8 +105,7 @@ public class Memo implements ByteSerializable, JsonSerializable {
custom_nonce = custom_nonce / 0x100; custom_nonce = custom_nonce / 0x100;
} }
} }
byte[] secret = toKey.getKey().getPubKeyPoint().multiply(fromKey.getPrivKey()).normalize().getXCoord().getEncoded();
byte[] secret = toKey.getKey().getPubKeyPoint().multiply(fromKey.getKey().getPrivKey()).normalize().getXCoord().getEncoded();
byte[] finalKey = new byte[secret.length + memo.nonce.length]; byte[] finalKey = new byte[secret.length + memo.nonce.length];
System.arraycopy(secret, 0, finalKey, 0, secret.length); System.arraycopy(secret, 0, finalKey, 0, secret.length);
System.arraycopy(memo.nonce, 0, finalKey, secret.length, memo.nonce.length); System.arraycopy(memo.nonce, 0, finalKey, secret.length, memo.nonce.length);
@ -120,16 +124,16 @@ public class Memo implements ByteSerializable, JsonSerializable {
/** /**
* returns the string coreesponding a encode memo * returns the string coreesponding a encode memo
* *
* @param fromKey The soruce key, need to have public key only * @param fromKey The soruce key, need to have public key only
* @param toKey The destination key, need to have private key access * @param toKey The destination key, need to have private key access
* @param msg The message to be decoded * @param msg The message to be decoded
* @param nonce The nonce used in the decoded message * @param nonce The nonce used in the decoded message
* @return The message * @return The message
*/ */
public static String decodeMessage(PublicKey fromKey, PublicKey toKey, byte[] msg, byte[] nonce) { public static String decodeMessage(PublicKey fromKey, ECKey toKey, byte[] msg, byte[] nonce) {
byte[] secret = fromKey.getKey().getPubKeyPoint().multiply(toKey.getKey().getPrivKey()).normalize().getXCoord().getEncoded(); byte[] secret = fromKey.getKey().getPubKeyPoint().multiply(toKey.getPrivKey()).normalize().getXCoord().getEncoded();
byte[] finalKey = new byte[secret.length + nonce.length]; byte[] finalKey = new byte[secret.length + nonce.length];
System.arraycopy(secret, 0, finalKey, 0, secret.length); System.arraycopy(secret, 0, finalKey, 0, secret.length);
System.arraycopy(nonce, 0, finalKey, secret.length, nonce.length); System.arraycopy(nonce, 0, finalKey, secret.length, nonce.length);
@ -142,15 +146,15 @@ public class Memo implements ByteSerializable, JsonSerializable {
} }
/** /**
* returns the string coreesponding a encode memo * returns the string corresponding a encode memo
* *
* @param fromKey The soruce key, need to have public key only * @param fromKey The source key, need to have public key only
* @param toKey The destination key, need to have private key access * @param toKey The destination key, need to have private key access
* @param message The message to be decoded * @param message The message to be decoded
* @param nonce The nonce used in the decoded message * @param nonce The nonce used in the decoded message
* @return The message * @return The message
*/ */
public static String decodeMessage(PublicKey fromKey, PublicKey toKey, String message, String nonce) { public static String decodeMessage(PublicKey fromKey, ECKey toKey, String message, String nonce) {
byte[] msg = new BigInteger(message, 16).toByteArray(); byte[] msg = new BigInteger(message, 16).toByteArray();
if (msg[0] == 0) { if (msg[0] == 0) {
byte[] temp = new byte[msg.length - 1]; byte[] temp = new byte[msg.length - 1];
@ -173,12 +177,14 @@ public class Memo implements ByteSerializable, JsonSerializable {
if ((this.from == null) || (this.to == null) || (this.nonce == null) || (this.message == null)) { if ((this.from == null) || (this.to == null) || (this.nonce == null) || (this.message == null)) {
return null; return null;
} }
org.spongycastle.math.ec.ECPoint point = ECKey.compressPoint(from.getPubKeyPoint());
PublicKey publicKey = new PublicKey(ECKey.fromPublicOnly(point));
JsonObject memoObject = new JsonObject(); JsonObject memoObject = new JsonObject();
memoObject.addProperty(KEY_FROM, this.from.getAddress()); memoObject.addProperty(KEY_FROM, publicKey.getAddress());
memoObject.addProperty(KEY_TO, this.to.getAddress()); memoObject.addProperty(KEY_TO, this.to.getAddress());
memoObject.addProperty(KEY_NONCE, new BigInteger(1, this.nonce).toString(10)); memoObject.addProperty(KEY_NONCE, new BigInteger(1, this.nonce).toString(10));
memoObject.addProperty(KEY_MESSAGE, new BigInteger(1, this.message).toString(16)); memoObject.addProperty(KEY_MESSAGE, new BigInteger(1, this.message).toString(16));
return memoObject; return memoObject;
} }
} }

View file

@ -1,6 +1,7 @@
package de.bitsharesmunich.graphenej.objects; package de.bitsharesmunich.graphenej.objects;
import de.bitsharesmunich.graphenej.PublicKey; import de.bitsharesmunich.graphenej.PublicKey;
import org.bitcoinj.core.ECKey;
/** /**
* Class to build a Memo Object * Class to build a Memo Object
@ -8,7 +9,7 @@ import de.bitsharesmunich.graphenej.PublicKey;
*/ */
public class MemoBuilder { public class MemoBuilder {
private PublicKey fromKey; private ECKey fromKey;
private PublicKey toKey; private PublicKey toKey;
private String message; private String message;
private long nonce = 0; private long nonce = 0;
@ -24,7 +25,7 @@ public class MemoBuilder {
* @param fromKey The Public Key of the sender * @param fromKey The Public Key of the sender
* @return The MemoBuilder * @return The MemoBuilder
*/ */
public MemoBuilder setFromKey(PublicKey fromKey) { public MemoBuilder setFromKey(ECKey fromKey) {
this.fromKey = fromKey; this.fromKey = fromKey;
return this; return this;
} }
@ -70,5 +71,4 @@ public class MemoBuilder {
} }
return Memo.encodeMessage(fromKey, toKey, message.getBytes(), nonce); return Memo.encodeMessage(fromKey, toKey, message.getBytes(), nonce);
} }
}
}