3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-01-31 23:32:16 +00:00

ECKey: don't crash when signing non-ASCII text

This commit is contained in:
Mike Hearn 2013-10-02 10:39:01 +02:00
parent e6250e575f
commit 14dae15150
2 changed files with 24 additions and 38 deletions

View File

@ -16,15 +16,16 @@
package com.google.bitcoin.core; package com.google.bitcoin.core;
import com.google.common.base.Charsets;
import com.google.common.primitives.UnsignedLongs; import com.google.common.primitives.UnsignedLongs;
import org.spongycastle.crypto.digests.RIPEMD160Digest; import org.spongycastle.crypto.digests.RIPEMD160Digest;
import org.spongycastle.util.encoders.Hex; import org.spongycastle.util.encoders.Hex;
import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.nio.charset.Charset;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.Arrays; import java.util.Arrays;
@ -48,6 +49,7 @@ public class Utils {
/** The string that prefixes all text messages signed using Bitcoin keys. */ /** The string that prefixes all text messages signed using Bitcoin keys. */
public static final String BITCOIN_SIGNED_MESSAGE_HEADER = "Bitcoin Signed Message:\n"; public static final String BITCOIN_SIGNED_MESSAGE_HEADER = "Bitcoin Signed Message:\n";
public static final byte[] BITCOIN_SIGNED_MESSAGE_HEADER_BYTES = BITCOIN_SIGNED_MESSAGE_HEADER.getBytes(Charsets.UTF_8);
// TODO: Replace this nanocoins business with something better. // TODO: Replace this nanocoins business with something better.
@ -510,20 +512,18 @@ public class Utils {
* <tt><p>[24] "Bitcoin Signed Message:\n" [message.length as a varint] message</p></tt> * <tt><p>[24] "Bitcoin Signed Message:\n" [message.length as a varint] message</p></tt>
*/ */
public static byte[] formatMessageForSigning(String message) { public static byte[] formatMessageForSigning(String message) {
VarInt size = new VarInt(message.length()); try {
int totalSize = 1 + BITCOIN_SIGNED_MESSAGE_HEADER.length() + size.getSizeInBytes() + message.length(); ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] result = new byte[totalSize]; bos.write(BITCOIN_SIGNED_MESSAGE_HEADER_BYTES.length);
int cursor = 0; bos.write(BITCOIN_SIGNED_MESSAGE_HEADER_BYTES);
result[cursor++] = (byte) BITCOIN_SIGNED_MESSAGE_HEADER.length(); byte[] messageBytes = message.getBytes(Charsets.UTF_8);
byte[] bytes = BITCOIN_SIGNED_MESSAGE_HEADER.getBytes(Charset.forName("UTF-8")); VarInt size = new VarInt(messageBytes.length);
System.arraycopy(bytes, 0, result, cursor, bytes.length); bos.write(size.encode());
cursor += bytes.length; bos.write(messageBytes);
bytes = size.encode(); return bos.toByteArray();
System.arraycopy(bytes, 0, result, cursor, bytes.length); } catch (IOException e) {
cursor += bytes.length; throw new RuntimeException(e); // Cannot happen.
bytes = message.getBytes(Charset.forName("UTF-8")); }
System.arraycopy(bytes, 0, result, cursor, bytes.length);
return result;
} }
// 00000001, 00000010, 00000100, 00001000, ... // 00000001, 00000010, 00000100, 00001000, ...

View File

@ -173,7 +173,7 @@ public class ECKeyTest {
@Test @Test
public void signTextMessage() throws Exception { public void signTextMessage() throws Exception {
ECKey key = new ECKey(); ECKey key = new ECKey();
String message = "Hello World!"; String message = "聡中本";
String signatureBase64 = key.signMessage(message); String signatureBase64 = key.signMessage(message);
log.info("Message signed with " + key.toAddress(MainNetParams.get()) + ": " + signatureBase64); log.info("Message signed with " + key.toAddress(MainNetParams.get()) + ": " + signatureBase64);
// Should verify correctly. // Should verify correctly.
@ -454,29 +454,15 @@ public class ECKeyTest {
} }
} }
private boolean checkSomeBytesAreNonZero(byte[] bytes) { private static boolean checkSomeBytesAreNonZero(byte[] bytes) {
if (bytes == null) { if (bytes == null) return false;
for (byte b : bytes) if (b != 0) return true;
return false; return false;
} else {
for (int i = 0; i < bytes.length; i++) {
if (bytes[i] != 0) {
return true;
}
}
return false;
}
} }
private boolean checkAllBytesAreZero(byte[] bytes) { private static boolean checkAllBytesAreZero(byte[] bytes) {
if (bytes == null) { if (bytes == null) return true;
return true; for (byte b : bytes) if (b != 0) return false;
} else {
for (int i = 0; i < bytes.length; i++) {
if (bytes[i] != 0) {
return false;
}
}
return true; return true;
} }
} }
}