mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-05-19 23:10:48 -04:00
Remove pubkey storage, remove duplicate sig keys
This commit is contained in:
parent
4883c90030
commit
07a9c7fd52
13 changed files with 101 additions and 139 deletions
|
@ -39,7 +39,7 @@ public class Encryption {
|
|||
public static final String ASYM_CIPHER = "RSA"; // TODO test with RSA/ECB/PKCS1Padding
|
||||
public static final String HMAC = "HmacSHA256";
|
||||
|
||||
public static KeyPair generateEncryptionKeyPair() {
|
||||
public static KeyPair generateKeyPair() {
|
||||
long ts = System.currentTimeMillis();
|
||||
try {
|
||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ENCR_KEY_ALGO);
|
||||
|
@ -187,7 +187,7 @@ public class Encryption {
|
|||
return cipher.doFinal(encryptedPayload);
|
||||
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
|
||||
| BadPaddingException | IllegalBlockSizeException e) {
|
||||
e.printStackTrace();
|
||||
// errors when trying to decrypt foreign messages are normal
|
||||
throw new CryptoException(e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,39 +17,28 @@
|
|||
|
||||
package io.bitsquare.common.crypto;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.security.KeyPair;
|
||||
|
||||
public class KeyRing {
|
||||
private static final Logger log = LoggerFactory.getLogger(KeyRing.class);
|
||||
|
||||
// Used for signing messages sent over the wire
|
||||
private final KeyPair signatureKeyPair;
|
||||
// Used for encrypting messages sent over the wire (hybrid encryption scheme is used, so it is used only to encrypt a symmetric session key)
|
||||
private final KeyPair encryptionKeyPair;
|
||||
|
||||
private final PubKeyRing pubKeyRing;
|
||||
|
||||
@Inject
|
||||
public KeyRing(KeyStorage keyStorage) {
|
||||
if (keyStorage.allKeyFilesExist()) {
|
||||
signatureKeyPair = keyStorage.loadKeyPair(KeyStorage.Key.MSG_SIGNATURE);
|
||||
encryptionKeyPair = keyStorage.loadKeyPair(KeyStorage.Key.MSG_ENCRYPTION);
|
||||
signatureKeyPair = keyStorage.loadKeyPair(KeyStorage.KeyEntry.MSG_SIGNATURE);
|
||||
encryptionKeyPair = keyStorage.loadKeyPair(KeyStorage.KeyEntry.MSG_ENCRYPTION);
|
||||
} else {
|
||||
// First time we create key pairs
|
||||
signatureKeyPair = Sig.generateKeyPair();
|
||||
encryptionKeyPair = Encryption.generateEncryptionKeyPair();
|
||||
encryptionKeyPair = Encryption.generateKeyPair();
|
||||
keyStorage.saveKeyRing(this);
|
||||
}
|
||||
pubKeyRing = new PubKeyRing(signatureKeyPair.getPublic(), signatureKeyPair.getPublic(), encryptionKeyPair.getPublic());
|
||||
}
|
||||
|
||||
//TODO
|
||||
public KeyPair getStorageSignatureKeyPair() {
|
||||
return signatureKeyPair;
|
||||
pubKeyRing = new PubKeyRing(signatureKeyPair.getPublic(), encryptionKeyPair.getPublic());
|
||||
}
|
||||
|
||||
public KeyPair getSignatureKeyPair() {
|
||||
|
|
|
@ -27,26 +27,26 @@ import java.io.File;
|
|||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.*;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.security.interfaces.DSAParams;
|
||||
import java.security.interfaces.DSAPrivateKey;
|
||||
import java.security.interfaces.RSAPrivateCrtKey;
|
||||
import java.security.spec.*;
|
||||
|
||||
public class KeyStorage {
|
||||
private static final Logger log = LoggerFactory.getLogger(KeyStorage.class);
|
||||
|
||||
public static final String DIR_KEY = "key.storage.dir";
|
||||
|
||||
public enum Key {
|
||||
STORAGE_SIGNATURE("storageSignature", Sig.KEY_ALGO),
|
||||
MSG_SIGNATURE("msgSignature", Sig.KEY_ALGO),
|
||||
MSG_ENCRYPTION("msgEncryption", Encryption.ENCR_KEY_ALGO);
|
||||
public enum KeyEntry {
|
||||
MSG_SIGNATURE("sig", Sig.KEY_ALGO),
|
||||
MSG_ENCRYPTION("enc", Encryption.ENCR_KEY_ALGO);
|
||||
|
||||
private final String fileName;
|
||||
private final String algorithm;
|
||||
|
||||
Key(String fileName, String algorithm) {
|
||||
KeyEntry(String fileName, String algorithm) {
|
||||
this.fileName = fileName;
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
@ -72,39 +72,26 @@ public class KeyStorage {
|
|||
private final File storageDir;
|
||||
|
||||
@Inject
|
||||
public KeyStorage(@Named(DIR_KEY) File storageDir) throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException {
|
||||
public KeyStorage(@Named(DIR_KEY) File storageDir) {
|
||||
this.storageDir = storageDir;
|
||||
}
|
||||
|
||||
public boolean allKeyFilesExist() {
|
||||
return fileExists(KeyStorage.Key.STORAGE_SIGNATURE) && fileExists(KeyStorage.Key.MSG_SIGNATURE) && fileExists(KeyStorage.Key.MSG_ENCRYPTION);
|
||||
return fileExists(KeyEntry.MSG_SIGNATURE) && fileExists(KeyEntry.MSG_ENCRYPTION);
|
||||
}
|
||||
|
||||
private boolean fileExists(Key key) {
|
||||
return new File(storageDir + "/" + key.getFileName() + "Pub.key").exists();
|
||||
private boolean fileExists(KeyEntry keyEntry) {
|
||||
return new File(storageDir + "/" + keyEntry.getFileName() + ".key").exists();
|
||||
}
|
||||
|
||||
public KeyPair loadKeyPair(Key key) {
|
||||
public KeyPair loadKeyPair(KeyEntry keyEntry) {
|
||||
// long now = System.currentTimeMillis();
|
||||
try {
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(key.getAlgorithm());
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(keyEntry.getAlgorithm());
|
||||
PublicKey publicKey;
|
||||
PrivateKey privateKey;
|
||||
|
||||
File filePublicKey = new File(storageDir + "/" + key.getFileName() + "Pub.key");
|
||||
try (FileInputStream fis = new FileInputStream(filePublicKey.getPath())) {
|
||||
byte[] encodedPublicKey = new byte[(int) filePublicKey.length()];
|
||||
fis.read(encodedPublicKey);
|
||||
|
||||
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedPublicKey);
|
||||
publicKey = keyFactory.generatePublic(publicKeySpec);
|
||||
} catch (InvalidKeySpecException | IOException e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.getMessage());
|
||||
throw new RuntimeException("Could not load key " + key.toString(), e);
|
||||
}
|
||||
|
||||
File filePrivateKey = new File(storageDir + "/" + key.getFileName() + "Priv.key");
|
||||
File filePrivateKey = new File(storageDir + "/" + keyEntry.getFileName() + ".key");
|
||||
try (FileInputStream fis = new FileInputStream(filePrivateKey.getPath())) {
|
||||
byte[] encodedPrivateKey = new byte[(int) filePrivateKey.length()];
|
||||
fis.read(encodedPrivateKey);
|
||||
|
@ -114,39 +101,46 @@ public class KeyStorage {
|
|||
} catch (InvalidKeySpecException | IOException e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.getMessage());
|
||||
throw new RuntimeException("Could not load key " + key.toString(), e);
|
||||
throw new RuntimeException("Could not load key " + keyEntry.toString(), e);
|
||||
}
|
||||
|
||||
if (privateKey instanceof RSAPrivateCrtKey) {
|
||||
RSAPrivateCrtKey rsaPrivateKey = (RSAPrivateCrtKey) privateKey;
|
||||
RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(rsaPrivateKey.getModulus(), rsaPrivateKey.getPublicExponent());
|
||||
publicKey = keyFactory.generatePublic(publicKeySpec);
|
||||
} else if (privateKey instanceof DSAPrivateKey) {
|
||||
DSAPrivateKey dsaPrivateKey = (DSAPrivateKey) privateKey;
|
||||
DSAParams dsaParams = dsaPrivateKey.getParams();
|
||||
BigInteger p = dsaParams.getP();
|
||||
BigInteger q = dsaParams.getQ();
|
||||
BigInteger g = dsaParams.getG();
|
||||
BigInteger y = g.modPow(dsaPrivateKey.getX(), p);
|
||||
KeySpec publicKeySpec = new DSAPublicKeySpec(y, p, q, g);
|
||||
publicKey = keyFactory.generatePublic(publicKeySpec);
|
||||
} else {
|
||||
throw new RuntimeException("Unsupported key algo" + keyEntry.getAlgorithm());
|
||||
}
|
||||
|
||||
//log.info("load completed in {} msec", System.currentTimeMillis() - now);
|
||||
return new KeyPair(publicKey, privateKey);
|
||||
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.getMessage());
|
||||
throw new RuntimeException("Could not load key " + key.toString(), e);
|
||||
throw new RuntimeException("Could not load key " + keyEntry.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void saveKeyRing(KeyRing keyRing) {
|
||||
saveKeyPair(keyRing.getStorageSignatureKeyPair(), Key.STORAGE_SIGNATURE.getFileName());
|
||||
saveKeyPair(keyRing.getSignatureKeyPair(), Key.MSG_SIGNATURE.getFileName());
|
||||
saveKeyPair(keyRing.getEncryptionKeyPair(), Key.MSG_ENCRYPTION.getFileName());
|
||||
savePrivateKey(keyRing.getSignatureKeyPair().getPrivate(), KeyEntry.MSG_SIGNATURE.getFileName());
|
||||
savePrivateKey(keyRing.getEncryptionKeyPair().getPrivate(), KeyEntry.MSG_ENCRYPTION.getFileName());
|
||||
}
|
||||
|
||||
public void saveKeyPair(KeyPair keyPair, String name) {
|
||||
public void savePrivateKey(PrivateKey privateKey, String name) {
|
||||
if (!storageDir.exists())
|
||||
storageDir.mkdir();
|
||||
|
||||
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyPair.getPublic().getEncoded());
|
||||
try (FileOutputStream fos = new FileOutputStream(storageDir + "/" + name + "Pub.key")) {
|
||||
fos.write(x509EncodedKeySpec.getEncoded());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.getMessage());
|
||||
throw new RuntimeException("Could not save key " + name, e);
|
||||
}
|
||||
|
||||
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyPair.getPrivate().getEncoded());
|
||||
try (FileOutputStream fos = new FileOutputStream(storageDir + "/" + name + "Priv.key")) {
|
||||
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey.getEncoded());
|
||||
try (FileOutputStream fos = new FileOutputStream(storageDir + "/" + name + ".key")) {
|
||||
fos.write(pkcs8EncodedKeySpec.getEncoded());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
|
|
|
@ -21,13 +21,14 @@ import io.bitsquare.app.Version;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.Serializable;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Same as KeyRing but with public keys only.
|
||||
|
@ -39,87 +40,65 @@ public class PubKeyRing implements Serializable {
|
|||
|
||||
transient private static final Logger log = LoggerFactory.getLogger(PubKeyRing.class);
|
||||
|
||||
private final byte[] storageSignaturePubKeyBytes;
|
||||
private final byte[] msgSignaturePubKeyBytes;
|
||||
private final byte[] msgEncryptionPubKeyBytes;
|
||||
private final byte[] signaturePubKeyBytes;
|
||||
private final byte[] encryptionPubKeyBytes;
|
||||
|
||||
transient private PublicKey storageSignaturePubKey;
|
||||
transient private PublicKey msgSignaturePubKey;
|
||||
transient private PublicKey signaturePubKey;
|
||||
transient private PublicKey encryptionPubKey;
|
||||
|
||||
public PubKeyRing(PublicKey storageSignaturePubKey, PublicKey msgSignaturePubKey, PublicKey encryptionPubKey) {
|
||||
this.storageSignaturePubKey = storageSignaturePubKey;
|
||||
this.msgSignaturePubKey = msgSignaturePubKey;
|
||||
public PubKeyRing(PublicKey signaturePubKey, PublicKey encryptionPubKey) {
|
||||
this.signaturePubKey = signaturePubKey;
|
||||
this.encryptionPubKey = encryptionPubKey;
|
||||
|
||||
this.storageSignaturePubKeyBytes = new X509EncodedKeySpec(storageSignaturePubKey.getEncoded()).getEncoded();
|
||||
this.msgSignaturePubKeyBytes = new X509EncodedKeySpec(msgSignaturePubKey.getEncoded()).getEncoded();
|
||||
this.msgEncryptionPubKeyBytes = new X509EncodedKeySpec(encryptionPubKey.getEncoded()).getEncoded();
|
||||
this.signaturePubKeyBytes = new X509EncodedKeySpec(signaturePubKey.getEncoded()).getEncoded();
|
||||
this.encryptionPubKeyBytes = new X509EncodedKeySpec(encryptionPubKey.getEncoded()).getEncoded();
|
||||
}
|
||||
|
||||
public PublicKey getStorageSignaturePubKey() {
|
||||
if (storageSignaturePubKey == null) {
|
||||
try {
|
||||
storageSignaturePubKey = KeyFactory.getInstance(Sig.KEY_ALGO).generatePublic(new X509EncodedKeySpec(storageSignaturePubKeyBytes));
|
||||
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.getMessage());
|
||||
}
|
||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
try {
|
||||
in.defaultReadObject();
|
||||
signaturePubKey = KeyFactory.getInstance(Sig.KEY_ALGO).generatePublic(new X509EncodedKeySpec(signaturePubKeyBytes));
|
||||
encryptionPubKey = KeyFactory.getInstance(Encryption.ENCR_KEY_ALGO).generatePublic(new X509EncodedKeySpec(encryptionPubKeyBytes));
|
||||
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.getMessage());
|
||||
} catch (Throwable t) {
|
||||
log.trace("Cannot be deserialized." + t.getMessage());
|
||||
}
|
||||
return storageSignaturePubKey;
|
||||
}
|
||||
|
||||
|
||||
public PublicKey getMsgSignaturePubKey() {
|
||||
if (msgSignaturePubKey == null) {
|
||||
try {
|
||||
msgSignaturePubKey = KeyFactory.getInstance(Sig.KEY_ALGO).generatePublic(new X509EncodedKeySpec(msgSignaturePubKeyBytes));
|
||||
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
return msgSignaturePubKey;
|
||||
public PublicKey getSignaturePubKey() {
|
||||
return signaturePubKey;
|
||||
}
|
||||
|
||||
public PublicKey getEncryptionPubKey() {
|
||||
if (encryptionPubKey == null) {
|
||||
try {
|
||||
encryptionPubKey = KeyFactory.getInstance(Encryption.ENCR_KEY_ALGO).generatePublic(new X509EncodedKeySpec(msgEncryptionPubKeyBytes));
|
||||
} catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
return encryptionPubKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (!(o instanceof PubKeyRing)) return false;
|
||||
|
||||
PubKeyRing that = (PubKeyRing) o;
|
||||
|
||||
if (!Arrays.equals(storageSignaturePubKeyBytes, that.storageSignaturePubKeyBytes)) return false;
|
||||
if (!Arrays.equals(msgSignaturePubKeyBytes, that.msgSignaturePubKeyBytes)) return false;
|
||||
return Arrays.equals(msgEncryptionPubKeyBytes, that.msgEncryptionPubKeyBytes);
|
||||
if (signaturePubKey != null ? !signaturePubKey.equals(that.signaturePubKey) : that.signaturePubKey != null)
|
||||
return false;
|
||||
return !(encryptionPubKey != null ? !encryptionPubKey.equals(that.encryptionPubKey) : that.encryptionPubKey != null);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = storageSignaturePubKeyBytes != null ? Arrays.hashCode(storageSignaturePubKeyBytes) : 0;
|
||||
result = 31 * result + (msgSignaturePubKeyBytes != null ? Arrays.hashCode(msgSignaturePubKeyBytes) : 0);
|
||||
result = 31 * result + (msgEncryptionPubKeyBytes != null ? Arrays.hashCode(msgEncryptionPubKeyBytes) : 0);
|
||||
int result = signaturePubKey != null ? signaturePubKey.hashCode() : 0;
|
||||
result = 31 * result + (encryptionPubKey != null ? encryptionPubKey.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PubKeyRing{" +
|
||||
"\nstorageSignaturePubKey=\n" + Util.pubKeyToString(getStorageSignaturePubKey()) +
|
||||
"\n\nmsgSignaturePubKey=\n" + Util.pubKeyToString(getMsgSignaturePubKey()) +
|
||||
"\n\nmsgSignaturePubKey=\n" + Util.pubKeyToString(getSignaturePubKey()) +
|
||||
"\n\nmsgEncryptionPubKey=\n" + Util.pubKeyToString(getEncryptionPubKey()) +
|
||||
'}';
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue