|
1 | 1 | package org.stellar.sdk; |
2 | 2 |
|
3 | 3 | import static java.lang.System.arraycopy; |
| 4 | +import static java.nio.charset.StandardCharsets.UTF_8; |
4 | 5 |
|
5 | 6 | import java.io.ByteArrayOutputStream; |
6 | 7 | import java.io.IOException; |
@@ -354,4 +355,72 @@ public int hashCode() { |
354 | 355 | Arrays.hashCode(publicKey.getEncoded()), |
355 | 356 | privateKey == null ? null : Arrays.hashCode(privateKey.getEncoded())); |
356 | 357 | } |
| 358 | + |
| 359 | + /** |
| 360 | + * Calculate the hash of a message according to <a |
| 361 | + * href="https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0053.md" |
| 362 | + * target="_blank">SEP-53</a>. |
| 363 | + * |
| 364 | + * @param message The message to hash |
| 365 | + * @return The SHA-256 hash of the prefixed message. |
| 366 | + */ |
| 367 | + private static byte[] calculateMessageHash(byte[] message) { |
| 368 | + final byte[] messagePrefix = "Stellar Signed Message:\n".getBytes(UTF_8); |
| 369 | + byte[] signedMessageBase = new byte[messagePrefix.length + message.length]; |
| 370 | + System.arraycopy(messagePrefix, 0, signedMessageBase, 0, messagePrefix.length); |
| 371 | + System.arraycopy(message, 0, signedMessageBase, messagePrefix.length, message.length); |
| 372 | + return Util.hash(signedMessageBase); |
| 373 | + } |
| 374 | + |
| 375 | + /** |
| 376 | + * Sign a message according to <a |
| 377 | + * href="https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0053.md" |
| 378 | + * target="_blank">SEP-53</a>. |
| 379 | + * |
| 380 | + * @param message The message to sign. |
| 381 | + * @return The signature bytes. |
| 382 | + */ |
| 383 | + public byte[] signMessage(String message) { |
| 384 | + return signMessage(message.getBytes(UTF_8)); |
| 385 | + } |
| 386 | + |
| 387 | + /** |
| 388 | + * Sign a message according to <a |
| 389 | + * href="https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0053.md" |
| 390 | + * target="_blank">SEP-53</a>. |
| 391 | + * |
| 392 | + * @param message The message to sign. |
| 393 | + * @return The signature bytes. |
| 394 | + */ |
| 395 | + public byte[] signMessage(byte[] message) { |
| 396 | + byte[] messageHash = calculateMessageHash(message); |
| 397 | + return sign(messageHash); |
| 398 | + } |
| 399 | + |
| 400 | + /** |
| 401 | + * Verify a <a |
| 402 | + * href="https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0053.md" |
| 403 | + * target="_blank">SEP-53</a> signed message. |
| 404 | + * |
| 405 | + * @param message The original message. |
| 406 | + * @param signature The signature to verify. |
| 407 | + * @return True if the signature is valid for the given message, false otherwise. |
| 408 | + */ |
| 409 | + public boolean verifyMessage(byte[] message, byte[] signature) { |
| 410 | + byte[] messageHash = calculateMessageHash(message); |
| 411 | + return verify(messageHash, signature); |
| 412 | + } |
| 413 | + |
| 414 | + /** |
| 415 | + * Verify a <a |
| 416 | + * href="https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0053.md" |
| 417 | + * target="_blank">SEP-53</a> signed message. |
| 418 | + * |
| 419 | + * @param message The original message. |
| 420 | + * @param signature The signature to verify. |
| 421 | + * @return True if the signature is valid for the given message, false otherwise. |
| 422 | + */ |
| 423 | + public boolean verifyMessage(String message, byte[] signature) { |
| 424 | + return verifyMessage(message.getBytes(UTF_8), signature); |
| 425 | + } |
357 | 426 | } |
0 commit comments