Replace message separation marker with message length prefix in digest as well

signature-implementation
Tal Moran 2015-11-12 23:46:25 +02:00
parent 5ffc08d07f
commit 1ef3d2357f
4 changed files with 27 additions and 18 deletions

View File

@ -8,13 +8,6 @@ import java.security.MessageDigest;
* Created by talm on 11/9/15. * Created by talm on 11/9/15.
*/ */
public interface Digest { public interface Digest {
/**
* Marker between messages
*/
public static final byte[] CONCAT_MARKER = {(byte) 0xde, (byte) 0xad, (byte) 0xbe, (byte) 0xef,
(byte) 0xba, (byte) 0x1d, (byte) 0xfa, (byte) 0xce};
/** /**
* Completes the hash computation by performing final operations such as padding. * Completes the hash computation by performing final operations such as padding.
* (copied from {@link MessageDigest#digest()}) * (copied from {@link MessageDigest#digest()})
@ -25,9 +18,7 @@ public interface Digest {
/** /**
* Updates the digest using the specified message (in serialized wire form) * Updates the digest using the specified message (in serialized wire form)
* *
* Includes a special message concatenation marker (the 64 bit message {@link #CONCAT_MARKER}) in the digest (digesting a single message * Each message is (automatically) prepended with its length as a 32-bit big-endian unsigned integer.
* will give a different result than the same message split into two messages).
* Messages must not contain the {@link #CONCAT_MARKER}) marker.
* @param msg * @param msg
* @return * @return
*/ */

View File

@ -41,8 +41,8 @@ public interface DigitalSignature {
/** /**
* Add msg to the content stream to be verified / signed. Each message is always (automatically) * Add msg to the content stream to be verified / signed. Each message is (automatically)
* prepended with its length as a 32-bit unsigned integer in network byte order. * prepended with its length as a 32-bit big-endian unsigned integer.
* *
* @param msg * @param msg
* @throws SignatureException * @throws SignatureException

View File

@ -2,13 +2,13 @@ package meerkat.crypto.concrete;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.ByteBuffer;
import java.security.*; import java.security.*;
import java.security.cert.*; import java.security.cert.*;
import java.security.cert.Certificate; import java.security.cert.Certificate;
import java.util.*; import java.util.*;
import com.google.protobuf.ByteString; import com.google.protobuf.ByteString;
import meerkat.crypto.Digest;
import meerkat.protobuf.Crypto; import meerkat.protobuf.Crypto;
import meerkat.util.Hex; import meerkat.util.Hex;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -27,7 +27,7 @@ import javax.security.auth.callback.UnsupportedCallbackException;
/** /**
* Sign and verify digital signatures. * Sign and verify digital signatures.
* <p/> *
* This class is not thread-safe (each thread should have its own instance). * This class is not thread-safe (each thread should have its own instance).
*/ */
public class ECDSASignature extends GlobalCryptoSetup implements DigitalSignature { public class ECDSASignature extends GlobalCryptoSetup implements DigitalSignature {
@ -38,6 +38,12 @@ public class ECDSASignature extends GlobalCryptoSetup implements DigitalSignatur
SHA256Digest digest = new SHA256Digest(); SHA256Digest digest = new SHA256Digest();
/**
* Buffer used to hold length in for hash update
*/
ByteBuffer lenBuf = ByteBuffer.allocate(4);
Map<ByteString, Certificate> loadedCertificates = new HashMap<>(); Map<ByteString, Certificate> loadedCertificates = new HashMap<>();
/** /**
@ -111,7 +117,7 @@ public class ECDSASignature extends GlobalCryptoSetup implements DigitalSignatur
/** /**
* Add the list of messages to the stream that is being verified/signed. * Add the list of messages to the stream that is being verified/signed.
* Messages are separated with {@link Digest#CONCAT_MARKER} * Messages are prepended with their length in 32-bit big-endian format.
* *
* @param msg * @param msg
* @throws SignatureException * @throws SignatureException
@ -119,10 +125,11 @@ public class ECDSASignature extends GlobalCryptoSetup implements DigitalSignatur
@Override @Override
public void updateContent(Message msg) throws SignatureException { public void updateContent(Message msg) throws SignatureException {
assert msg != null; assert msg != null;
int len = msg.getSerializedSize();
byte[] lenBytes = { (byte) ((len >>> 24) & 0xff), (byte) ((len >>> 16) & 0xff), (byte) ((len >>> 8) & 0xff), (byte) (len & 0xff) }; lenBuf.clear();
signer.update(lenBytes); lenBuf.putInt(msg.getSerializedSize());
lenBuf.flip();
signer.update(lenBuf);
signer.update(msg.toByteString().asReadOnlyByteBuffer()); signer.update(msg.toByteString().asReadOnlyByteBuffer());
} }

View File

@ -6,6 +6,7 @@ import meerkat.crypto.Digest;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.nio.ByteBuffer;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
@ -18,6 +19,11 @@ public class SHA256Digest extends GlobalCryptoSetup implements Digest {
MessageDigest hash; MessageDigest hash;
/**
* Used to convert length to bytes in proper order.
*/
ByteBuffer lenBuf = ByteBuffer.allocate(4);
/** /**
* Instantiate with a specified algorithm. * Instantiate with a specified algorithm.
* @param algorithm * @param algorithm
@ -56,6 +62,11 @@ public class SHA256Digest extends GlobalCryptoSetup implements Digest {
@Override @Override
public void update(Message msg) { public void update(Message msg) {
lenBuf.clear();
lenBuf.putInt(msg.getSerializedSize());
lenBuf.flip();
hash.update(lenBuf);
hash.update(msg.toByteString().asReadOnlyByteBuffer()); hash.update(msg.toByteString().asReadOnlyByteBuffer());
} }