Making PublicKey class throw exception when passed private key data

master
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.testCreateBinFile();
// test.testImportBinFile();
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 org.bitcoinj.core.ECKey;
import org.spongycastle.math.ec.ECPoint;
/**
* Created by nelson on 11/30/16.
@ -10,6 +11,9 @@ public class PublicKey implements ByteSerializable {
private ECKey publicKey;
public PublicKey(ECKey key) {
if(key.hasPrivKey()){
throw new IllegalStateException("Passing a private key to PublicKey constructor");
}
this.publicKey = key;
}
@ -19,10 +23,20 @@ public class PublicKey implements ByteSerializable {
@Override
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(){
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 {
// 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()));
Memo memo = new MemoBuilder().setFromKey(from).setToKey(to).setMessage("sample message").build();
@ -377,15 +377,44 @@ public class Test {
}
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 {
WebSocketFactory factory = new WebSocketFactory().setConnectionTimeout(5000);
WebSocket mWebSocket = factory.createSocket(WITNESS_URL);
mWebSocket.addListener(new GetAccountByName("bilthon-83", mListener));
SSLContext context = null;
context = NaiveSSLContext.getInstance("TLS");
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();
} catch (IOException e) {
System.out.println("IOException. Msg: " + e.getMessage());
} catch (WebSocketException e) {
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 {
System.out.println("Using brain key: " + Main.BILTHON_5_BRAIN_KEY);
// 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();
System.out.println("Private key..................: " + Util.bytesToHex(key.getSecretBytes()));
@ -707,13 +736,13 @@ public class Test {
public void testDecodeMemo() {
PublicKey from = new PublicKey((new BrainKey(Main.BILTHON_83_BRAIN_KEY, 0).getPrivateKey()));
PublicKey to = new PublicKey(new BrainKey(Main.BILTHON_5_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()));
Memo sendMemo = new MemoBuilder().setFromKey(from).setToKey(to).setMessage("test message").build();
JsonElement memoJson = sendMemo.toJsonObject();
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.interfaces.ByteSerializable;
import de.bitsharesmunich.graphenej.interfaces.JsonSerializable;
import org.bitcoinj.core.ECKey;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@ -17,13 +19,13 @@ import java.security.SecureRandom;
* Created by nelson on 11/9/16.
*/
public class Memo implements ByteSerializable, JsonSerializable {
public final static String TAG = "Memo";
public static final String KEY_FROM = "from";
public static final String KEY_TO = "to";
public static final String KEY_NONCE = "nonce";
public static final String KEY_MESSAGE = "message";
private PublicKey from;
private ECKey from;
private PublicKey to;
private final byte[] nonce = new byte[8];
private byte[] message;
@ -36,7 +38,7 @@ public class Memo implements ByteSerializable, JsonSerializable {
this.to = null;
this.message = null;
}
/**
* Implement metod, serialized this Object
* @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++) {
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
* @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);
}
/**
* Encode a message a return a memo with that message encoded
*
*
* @param fromKey The source destination, need to have a private key accesss
* @param toKey The destination, needs only the public key access
* @param msg The message in bytes
* @param custom_nonce the custom nonce to be use or 0 to create a new one
* @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();
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
@ -84,7 +89,7 @@ public class Memo implements ByteSerializable, JsonSerializable {
if (custom_nonce == 0) {
SecureRandomStrengthener randomStrengthener = SecureRandomStrengthener.getInstance();
//randomStrengthener.addEntropySource(new AndroidRandomSource());
// randomStrengthener.addEntropySource(new AndroidRandomSource());
SecureRandom secureRandom = randomStrengthener.generateAndSeedRandomNumberGenerator();
secureRandom.nextBytes(memo.nonce);
@ -100,8 +105,7 @@ public class Memo implements ByteSerializable, JsonSerializable {
custom_nonce = custom_nonce / 0x100;
}
}
byte[] secret = toKey.getKey().getPubKeyPoint().multiply(fromKey.getKey().getPrivKey()).normalize().getXCoord().getEncoded();
byte[] secret = toKey.getKey().getPubKeyPoint().multiply(fromKey.getPrivKey()).normalize().getXCoord().getEncoded();
byte[] finalKey = new byte[secret.length + memo.nonce.length];
System.arraycopy(secret, 0, finalKey, 0, secret.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
*
*
* @param fromKey The soruce key, need to have public key only
* @param toKey The destination key, need to have private key access
* @param msg The message to be decoded
* @param nonce The nonce used in the decoded 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];
System.arraycopy(secret, 0, finalKey, 0, secret.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
*
* @param fromKey The soruce key, need to have public key only
* returns the string corresponding a encode memo
*
* @param fromKey The source key, need to have public key only
* @param toKey The destination key, need to have private key access
* @param message The message to be decoded
* @param nonce The nonce used in the decoded 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();
if (msg[0] == 0) {
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)) {
return null;
}
org.spongycastle.math.ec.ECPoint point = ECKey.compressPoint(from.getPubKeyPoint());
PublicKey publicKey = new PublicKey(ECKey.fromPublicOnly(point));
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_NONCE, new BigInteger(1, this.nonce).toString(10));
memoObject.addProperty(KEY_MESSAGE, new BigInteger(1, this.message).toString(16));
return memoObject;
}
}

View File

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