I don't believe it - encryption works!!!

This commit is contained in:
Christian Basler 2015-05-12 19:04:00 +02:00
parent f23f432f07
commit 46bb00c0aa
12 changed files with 264 additions and 145 deletions

View File

@ -16,11 +16,15 @@
package ch.dissem.bitmessage.demo;
import ch.dissem.bitmessage.BitmessageContext;
import ch.dissem.bitmessage.entity.BitmessageAddress;
import ch.dissem.bitmessage.entity.ObjectMessage;
import ch.dissem.bitmessage.entity.payload.ObjectType;
import ch.dissem.bitmessage.entity.payload.Pubkey;
import ch.dissem.bitmessage.entity.payload.*;
import ch.dissem.bitmessage.inventory.JdbcAddressRepository;
import ch.dissem.bitmessage.inventory.JdbcInventory;
import ch.dissem.bitmessage.inventory.JdbcNodeRegistry;
import ch.dissem.bitmessage.networking.NetworkNode;
import ch.dissem.bitmessage.ports.NetworkHandler;
import ch.dissem.bitmessage.utils.Base58;
import ch.dissem.bitmessage.utils.Encode;
import ch.dissem.bitmessage.utils.Security;
@ -31,6 +35,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
/**
* Created by chris on 06.04.15.
@ -39,43 +44,45 @@ public class Main {
private final static Logger LOG = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) throws IOException {
final BitmessageAddress address = new BitmessageAddress("BM-2D9Vc5rFxxR5vTi53T9gkLfemViHRMVLQZ");
final BitmessageAddress address = new BitmessageAddress("BM-87hJ99tPAXxtetvnje7Z491YSvbEtBJVc5e");
// BitmessageContext ctx = new BitmessageContext.Builder()
// .addressRepo(new JdbcAddressRepository())
// .inventory(new JdbcInventory())
// .nodeRegistry(new JdbcNodeRegistry())
// .networkHandler(new NetworkNode())
// .port(48444)
// .streams(1)
// .build();
//
// ctx.getNetworkHandler().start(new NetworkHandler.MessageListener() {
// @Override
// public void receive(ObjectPayload payload) {
//// LOG.info("message received: " + payload);
//// System.out.print('.');
// if (payload instanceof V3Pubkey) {
// V3Pubkey pubkey = (V3Pubkey) payload;
// try {
// address.setPubkey(pubkey);
// System.out.println(address);
// } catch (Exception ignore) {
// System.err.println("Received pubkey we didn't request.");
// }
// }
// }
// });
//
// Scanner scanner = new Scanner(System.in);
BitmessageContext ctx = new BitmessageContext.Builder()
.addressRepo(new JdbcAddressRepository())
.inventory(new JdbcInventory())
.nodeRegistry(new JdbcNodeRegistry())
.networkHandler(new NetworkNode())
.port(48444)
.streams(1)
.build();
ctx.getNetworkHandler().start(new NetworkHandler.MessageListener() {
@Override
public void receive(ObjectPayload payload) {
// LOG.info("message received: " + payload);
// System.out.print('.');
if (payload instanceof V4Pubkey) {
V4Pubkey pubkey = (V4Pubkey) payload;
if (Arrays.equals(address.getTag(), pubkey.getTag())) {
System.out.println("Pubkey found!");
try {
address.setPubkey(pubkey);
} catch (Exception ignore) {
System.err.println("Received pubkey we didn't request.");
}
}
}
}
});
Scanner scanner = new Scanner(System.in);
// System.out.println("Press Enter to request pubkey for address " + address);
// scanner.nextLine();
// ctx.send(1, address.getVersion(), new GetPubkey(address), 3000, 1000, 1000);
//
// System.out.println("Press Enter to exit");
// scanner.nextLine();
// LOG.info("Shutting down client");
// ctx.getNetworkHandler().stop();
System.out.println("Press Enter to exit");
scanner.nextLine();
LOG.info("Shutting down client");
ctx.getNetworkHandler().stop();
List<ObjectMessage> objects = new JdbcInventory().getObjects(address.getStream(), address.getVersion(), ObjectType.PUBKEY);
@ -84,17 +91,18 @@ public class Main {
for (ObjectMessage o : objects) {
// if (!o.isSignatureValid()) System.out.println("Invalid signature.");
// System.out.println(o.getPayload().getSignature().length);
Pubkey pubkey = (Pubkey) o.getPayload();
if (Arrays.equals(address.getRipe(), pubkey.getRipe()))
V4Pubkey pubkey = (V4Pubkey) o.getPayload();
if (Arrays.equals(address.getTag(), pubkey.getTag())) {
System.out.println("Pubkey found!");
try {
address.setPubkey(pubkey);
System.out.println(address);
} catch (Exception ignore) {
System.out.println("But setPubkey failed? " + address.getRipe().length + "/" + pubkey.getRipe().length);
System.out.println("Failed address: " + generateAddress(address.getStream(), address.getVersion(), pubkey.getRipe()));
if (Arrays.equals(address.getRipe(), pubkey.getRipe())) {
ignore.printStackTrace();
try {
System.out.println("IV: "+o.getInventoryVector());
address.setPubkey(pubkey);
} catch (Exception ignore) {
System.out.println("But setPubkey failed? " + address.getRipe().length + "/" + pubkey.getRipe().length);
System.out.println("Failed address: " + generateAddress(address.getStream(), address.getVersion(), pubkey.getRipe()));
if (Arrays.equals(address.getRipe(), pubkey.getRipe())) {
ignore.printStackTrace();
}
}
}
}

View File

@ -64,7 +64,8 @@ public class BitmessageAddress {
this.tag = Arrays.copyOfRange(checksum, 32, 64);
this.privateEncryptionKey = Arrays.copyOfRange(checksum, 0, 32);
// but for the address and its checksum they need to be stripped
os.write(Bytes.stripLeadingZeros(ripe));
int offset = Bytes.numberOfLeadingZeros(ripe);
os.write(ripe, offset, ripe.length - offset);
checksum = Security.doubleSha512(os.toByteArray(), ripe);
os.write(checksum, 0, 4);
this.address = "BM-" + Base58.encode(os.toByteArray());
@ -73,10 +74,14 @@ public class BitmessageAddress {
}
}
private BitmessageAddress(Pubkey publicKey) {
this(publicKey.getVersion(), publicKey.getStream(), publicKey.getRipe());
this.pubkey = publicKey;
}
public BitmessageAddress(PrivateKey privateKey) {
this(privateKey.getPubkey().getVersion(), privateKey.getPubkey().getStream(), privateKey.getPubkey().getRipe());
this(privateKey.getPubkey());
this.privateKey = privateKey;
this.pubkey = privateKey.getPubkey();
}
public BitmessageAddress(String address) {
@ -104,6 +109,18 @@ public class BitmessageAddress {
}
}
public static byte[] calculateTag(long version, long stream, byte[] ripe) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
Encode.varInt(version, out);
Encode.varInt(stream, out);
out.write(ripe);
return Arrays.copyOfRange(Security.doubleSha512(out.toByteArray()), 32, 64);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public long getStream() {
return stream;
}

View File

@ -27,7 +27,6 @@ import org.bouncycastle.crypto.paddings.PKCS7Padding;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.bouncycastle.jce.interfaces.ECPublicKey;
import org.bouncycastle.math.ec.ECPoint;
import java.io.*;
@ -41,36 +40,37 @@ import java.util.Arrays;
public class CryptoBox implements Streamable {
private final byte[] initializationVector;
private final int curveType;
private final byte[] xComponent;
private final byte[] yComponent;
private final ECPoint R;
private final byte[] mac;
private byte[] encrypted;
public CryptoBox(Streamable data, byte[] encryptionKey) {
this(data, Security.keyToPoint(encryptionKey));
}
public CryptoBox(Streamable data, ECPoint K) {
curveType = 0x02CA;
// 1. The destination public key is called K.
ECPublicKey K = Security.getPublicKey(encryptionKey);
// 2. Generate 16 random bytes using a secure random number generator. Call them IV.
initializationVector = Security.randomBytes(16);
// 3. Generate a new random EC key pair with private key called r and public key called R.
// TODO
BigInteger r = null;
byte[] r = Security.randomBytes(64);
R = Security.createPublicKey(r);
// 4. Do an EC point multiply with public key K and private key r. This gives you public key P.
ECPoint P = K.getQ().multiply(r).normalize();
xComponent = Bytes.stripLeadingZeros(P.getXCoord().getEncoded());
yComponent = Bytes.stripLeadingZeros(P.getYCoord().getEncoded());
ECPoint P = K.multiply(Security.keyToBigInt(r)).normalize();
byte[] X = P.getXCoord().getEncoded();
// 5. Use the X component of public key P and calculate the SHA512 hash H.
byte[] H = Security.sha512(xComponent);
byte[] H = Security.sha512(X);
// 6. The first 32 bytes of H are called key_e and the last 32 bytes are called key_m.
byte[] key_e = Arrays.copyOfRange(H, 0, 32);
byte[] key_m = Arrays.copyOfRange(H, H.length - 32, 32);
byte[] key_m = Arrays.copyOfRange(H, 32, 64);
// 7. Pad the input text to a multiple of 16 bytes, in accordance to PKCS7.
// 8. Encrypt the data with AES-256-CBC, using IV as initialization vector, key_e as encryption key and the padded input text as payload. Call the output cipher text.
encrypted = null; // TODO
encrypted = crypt(true, Bytes.from(data), key_e);
// 9. Calculate a 32 byte MAC with HMACSHA256, using key_m as salt and IV + R + cipher text as data. Call the output MAC.
mac = null; // TODO
mac = calculateMac(key_m);
// The resulting data is: IV + R + cipher text + MAC
}
@ -78,8 +78,7 @@ public class CryptoBox implements Streamable {
private CryptoBox(Builder builder) {
initializationVector = builder.initializationVector;
curveType = builder.curveType;
xComponent = builder.xComponent;
yComponent = builder.yComponent;
R = Security.createPoint(builder.xComponent, builder.yComponent);
encrypted = builder.encrypted;
mac = builder.mac;
}
@ -101,53 +100,65 @@ public class CryptoBox implements Streamable {
*/
public InputStream decrypt(byte[] privateKey) {
// 1. The private key used to decrypt is called k.
BigInteger K = Security.keyToBigInt(privateKey);
BigInteger k = Security.keyToBigInt(privateKey);
// 2. Do an EC point multiply with private key k and public key R. This gives you public key P.
ECPublicKey R = Security.getPublicKey(xComponent, yComponent);
ECPoint P = R.getQ().multiply(K).normalize();
ECPoint P = R.multiply(k).normalize();
// 3. Use the X component of public key P and calculate the SHA512 hash H.
byte[] sha512key = Security.sha512(Bytes.expand(P.getXCoord().toBigInteger().toByteArray(), 32));
byte[] H = Security.sha512(P.getXCoord().getEncoded());
// 4. The first 32 bytes of H are called key_e and the last 32 bytes are called key_m.
byte[] key_e = Arrays.copyOfRange(sha512key, 0, 32);
byte[] key_m = Arrays.copyOfRange(sha512key, 32, 64);
byte[] key_e = Arrays.copyOfRange(H, 0, 32);
byte[] key_m = Arrays.copyOfRange(H, 32, 64);
// 5. Calculate MAC' with HMACSHA256, using key_m as salt and IV + R + cipher text as data.
ByteArrayOutputStream macData = new ByteArrayOutputStream();
try {
writeWithoutMAC(macData);
} catch (IOException e) {
throw new RuntimeException(e);
}
// 6. Compare MAC with MAC'. If not equal, decryption will fail.
if (!Arrays.equals(mac, Security.mac(key_m, macData.toByteArray()))) {
if (!Arrays.equals(mac, calculateMac(key_m))) {
throw new RuntimeException("Invalid MAC while decrypting");
}
// 7. Decrypt the cipher text with AES-256-CBC, using IV as initialization vector, key_e as decryption key
// and the cipher text as payload. The output is the padded input text.
return new ByteArrayInputStream(crypt(false, encrypted, key_e));
}
private byte[] calculateMac(byte[] key_m) {
try {
ByteArrayOutputStream macData = new ByteArrayOutputStream();
writeWithoutMAC(macData);
return Security.mac(key_m, macData.toByteArray());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private byte[] crypt(boolean encrypt, byte[] data, byte[] key_e) {
BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine()), new PKCS7Padding());
CipherParameters params = new ParametersWithIV(new KeyParameter(key_e), initializationVector);
cipher.init(false, params);
cipher.init(encrypt, params);
byte[] buffer = new byte[cipher.getOutputSize(encrypted.length)];
int length = cipher.processBytes(encrypted, 0, encrypted.length, buffer, 0);
byte[] buffer = new byte[cipher.getOutputSize(data.length)];
int length = cipher.processBytes(data, 0, data.length, buffer, 0);
try {
length += cipher.doFinal(buffer, length);
} catch (InvalidCipherTextException e) {
throw new IllegalArgumentException(e);
}
return new ByteArrayInputStream(buffer, 0, length);
if (length < buffer.length) {
return Arrays.copyOfRange(buffer, 0, length);
}
return buffer;
}
private void writeWithoutMAC(OutputStream stream) throws IOException {
stream.write(initializationVector);
Encode.int16(curveType, stream);
Encode.int16(xComponent.length, stream);
stream.write(xComponent);
Encode.int16(yComponent.length, stream);
stream.write(yComponent);
byte[] x = R.getXCoord().getEncoded();
byte[] y = R.getYCoord().getEncoded();
Encode.int16(x.length, stream);
stream.write(x);
Encode.int16(y.length, stream);
stream.write(y);
stream.write(encrypted);
}

View File

@ -21,6 +21,7 @@ import ch.dissem.bitmessage.utils.Decode;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
/**
* In cases we don't know what to do with an object, we just store its bytes and send it again - we don't really
@ -53,4 +54,22 @@ public class GenericPayload extends ObjectPayload {
public void write(OutputStream stream) throws IOException {
stream.write(data);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
GenericPayload that = (GenericPayload) o;
if (stream != that.stream) return false;
return Arrays.equals(data, that.data);
}
@Override
public int hashCode() {
int result = (int) (stream ^ (stream >>> 32));
result = 31 * result + Arrays.hashCode(data);
return result;
}
}

View File

@ -34,7 +34,7 @@ public abstract class ObjectPayload implements Streamable {
return false;
}
public void writeBytesToSign(OutputStream out) throws IOException{
public void writeBytesToSign(OutputStream out) throws IOException {
// nothing to do
}

View File

@ -16,7 +16,9 @@
package ch.dissem.bitmessage.entity.payload;
import ch.dissem.bitmessage.entity.BitmessageAddress;
import ch.dissem.bitmessage.utils.Decode;
import ch.dissem.bitmessage.utils.Security;
import java.io.IOException;
import java.io.InputStream;
@ -40,11 +42,10 @@ public class V4Pubkey extends Pubkey {
this.encrypted = encrypted;
}
public V4Pubkey(byte[] tag, V3Pubkey decrypted) {
public V4Pubkey(V3Pubkey decrypted) {
this.stream = decrypted.stream;
this.tag = tag;
this.tag = BitmessageAddress.calculateTag(4, decrypted.getStream(), decrypted.getRipe());
this.decrypted = decrypted;
this.encrypted = new CryptoBox(decrypted, null);
}
public static V4Pubkey read(InputStream in, long stream, int length) throws IOException {
@ -53,6 +54,11 @@ public class V4Pubkey extends Pubkey {
CryptoBox.read(in, length - 32));
}
public void encrypt(byte[] privateKey) throws IOException {
if (getSignature() == null) throw new IllegalStateException("Pubkey must be signed before encryption.");
this.encrypted = new CryptoBox(decrypted, Security.createPublicKey(privateKey));
}
public void decrypt(byte[] privateKey) throws IOException {
decrypted = V3Pubkey.read(encrypted.decrypt(privateKey), stream);
}

View File

@ -60,6 +60,14 @@ public class PrivateKey implements Streamable {
}
}
public byte[] getPrivateSigningKey() {
return privateSigningKey;
}
public byte[] getPrivateEncryptionKey() {
return privateEncryptionKey;
}
public static PrivateKey read(InputStream is) throws IOException {
int version = (int) Decode.varInt(is);
long stream = Decode.varInt(is);

View File

@ -82,7 +82,6 @@ public class Factory {
.build();
case 4:
return new V4Pubkey(
null, // FIXME: calculate tag
new V3Pubkey.Builder()
.stream(stream)
.publicSigningKey(publicSigningKey)

View File

@ -16,6 +16,12 @@
package ch.dissem.bitmessage.utils;
import ch.dissem.bitmessage.entity.Streamable;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
/**
* A helper class for working with byte arrays interpreted as unsigned big endian integers.
*/
@ -41,6 +47,9 @@ public class Bytes {
}
}
/**
* Returns true if a < b.
*/
public static boolean lt(byte[] a, byte[] b) {
byte[] max = (a.length > b.length ? a : b);
byte[] min = (max == a ? b : a);
@ -57,6 +66,9 @@ public class Bytes {
return false;
}
/**
* Returns true if a < b, where the first [size] bytes are checked.
*/
public static boolean lt(byte[] a, byte[] b, int size) {
for (int i = 0; i < size; i++) {
if (a[i] != b[i]) {
@ -123,14 +135,25 @@ public class Bytes {
throw new IllegalArgumentException("'" + c + "' is not a valid hex value");
}
public static byte[] stripLeadingZeros(byte[] bytes) {
for (int i = 0; i < bytes.length; i++) {
if (bytes[i] != 0) {
byte[] result = new byte[bytes.length - i];
System.arraycopy(bytes, i, result, 0, bytes.length - i);
return result;
}
public static int numberOfLeadingZeros(byte[] bytes) {
int i;
for (i = 0; i < bytes.length; i++) {
if (bytes[i] != 0) return i;
}
return i;
}
public static byte[] stripLeadingZeros(byte[] bytes) {
return Arrays.copyOfRange(bytes, numberOfLeadingZeros(bytes), bytes.length);
}
public static byte[] from(Streamable data) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
data.write(out);
return out.toByteArray();
} catch (IOException e) {
throw new RuntimeException(e);
}
return new byte[0];
}
}

View File

@ -23,10 +23,9 @@ import ch.dissem.bitmessage.ports.ProofOfWorkEngine;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.ec.CustomNamedCurves;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.interfaces.ECPublicKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.math.ec.ECPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -35,7 +34,6 @@ import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.*;
import java.util.Arrays;
/**
@ -162,62 +160,46 @@ public class Security {
public static Pubkey createPubkey(long version, long stream, byte[] privateSigningKey, byte[] privateEncryptionKey,
long nonceTrialsPerByte, long extraBytes, Pubkey.Feature... features) {
return Factory.createPubkey(version, stream,
createPublicKey(privateSigningKey),
createPublicKey(privateEncryptionKey),
createPublicKey(privateSigningKey).getEncoded(false),
createPublicKey(privateEncryptionKey).getEncoded(false),
nonceTrialsPerByte, extraBytes, features);
}
private static byte[] createPublicKey(byte[] privateKey) {
return EC_DOMAIN_PARAMETERS.getG().multiply(keyToBigInt(privateKey)).getEncoded(false);
public static ECPoint createPublicKey(byte[] privateKey) {
return EC_DOMAIN_PARAMETERS.getG().multiply(keyToBigInt(privateKey)).normalize();
}
public static BigInteger keyToBigInt(byte[] privateKey) {
return new BigInteger(1, privateKey);
}
private static ECPoint keyToPoint(byte[] publicKey) {
BigInteger x = new BigInteger(Arrays.copyOfRange(publicKey, 1, 33));
BigInteger y = new BigInteger(Arrays.copyOfRange(publicKey, 33, 65));
return new ECPoint(x, y);
public static ECPoint keyToPoint(byte[] publicKey) {
BigInteger x = new BigInteger(1, Arrays.copyOfRange(publicKey, 1, 33));
BigInteger y = new BigInteger(1, Arrays.copyOfRange(publicKey, 33, 65));
return EC_DOMAIN_PARAMETERS.getCurve().createPoint(x, y);
}
public static ECPoint createPoint(byte[] x, byte[] y) {
return EC_DOMAIN_PARAMETERS.getCurve().createPoint(
new BigInteger(1, x),
new BigInteger(1, y)
);
}
public static boolean isSignatureValid(byte[] bytesToSign, byte[] signature, Pubkey pubkey) {
ECPoint W = keyToPoint(pubkey.getSigningKey());
try {
ECParameterSpec param = null;
KeySpec keySpec = new ECPublicKeySpec(W, param);
PublicKey publicKey = KeyFactory.getInstance("ECDSA", "BC").generatePublic(keySpec);
Signature sig = Signature.getInstance("ECDSA", "BC");
sig.initVerify(publicKey);
sig.update(bytesToSign);
return sig.verify(signature);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static ECPublicKey getPublicKey(byte[] publicKey) {
if (publicKey[0] != 0x04) throw new IllegalArgumentException("Public key starting with 0x04 expected");
return getPublicKey(
Arrays.copyOfRange(publicKey, 1, 33),
Arrays.copyOfRange(publicKey, 33, 65)
);
}
public static ECPublicKey getPublicKey(byte[] X, byte[] Y) {
try {
ECPoint w = new ECPoint(keyToBigInt(X), keyToBigInt(Y));
EllipticCurve curve = EC5Util.convertCurve(EC_DOMAIN_PARAMETERS.getCurve(), EC_CURVE_PARAMETERS.getSeed());
ECParameterSpec params = EC5Util.convertSpec(curve, ECNamedCurveTable.getParameterSpec(EC_CURVE_NAME));
ECPublicKeySpec keySpec = new ECPublicKeySpec(w, params);
return (ECPublicKey) getKeyFactory().generatePublic(keySpec);
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
}
}
private static KeyFactory getKeyFactory() throws NoSuchProviderException, NoSuchAlgorithmException {
return KeyFactory.getInstance("EC", "BC");
// try {
// ECParameterSpec param = null;
// KeySpec keySpec = new ECPublicKeySpec(W, param);
// PublicKey publicKey = KeyFactory.getInstance("ECDSA", "BC").generatePublic(keySpec);
//
// Signature sig = Signature.getInstance("ECDSA", "BC");
// sig.initVerify(publicKey);
// sig.update(bytesToSign);
// return sig.verify(signature);
// } catch (Exception e) {
// throw new RuntimeException(e);
// }
return false; // TODO
}
}

View File

@ -25,6 +25,7 @@ import org.junit.Test;
import java.io.IOException;
import static ch.dissem.bitmessage.entity.payload.Pubkey.Feature.DOES_ACK;
import static org.junit.Assert.*;
public class BitmessageAddressTest {
@ -53,7 +54,7 @@ public class BitmessageAddressTest {
@Test
public void testCreateAddress() {
BitmessageAddress address = new BitmessageAddress(new PrivateKey(0, 0, 0));
BitmessageAddress address = new BitmessageAddress(new PrivateKey(1, 1000, 1000, DOES_ACK));
assertNotNull(address.getPubkey());
}

View File

@ -0,0 +1,45 @@
/*
* Copyright 2015 Christian Basler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.dissem.bitmessage.utils;
import ch.dissem.bitmessage.entity.payload.CryptoBox;
import ch.dissem.bitmessage.entity.payload.GenericPayload;
import ch.dissem.bitmessage.entity.valueobject.PrivateKey;
import org.junit.Ignore;
import org.junit.Test;
import java.io.IOException;
import java.security.KeyPair;
import static org.junit.Assert.assertEquals;
/**
* Created by chris on 10.05.15.
*/
public class EncryptionTest {
@Test
public void ensureDecryptedDataIsSameAsBeforeEncryption() throws IOException {
GenericPayload before = new GenericPayload(1, Security.randomBytes(100));
PrivateKey privateKey = new PrivateKey(1, 1000, 1000);
CryptoBox cryptoBox = new CryptoBox(before, privateKey.getPubkey().getEncryptionKey());
GenericPayload after = GenericPayload.read(cryptoBox.decrypt(privateKey.getPrivateEncryptionKey()), 1, 100);
assertEquals(before, after);
}
}