Java源码示例:org.whispersystems.libsignal.LegacyMessageException
示例1
public IncomingTextMessage decrypt(Context context, IncomingTextMessage message)
throws LegacyMessageException, InvalidMessageException, DuplicateMessageException,
NoSessionException, UntrustedIdentityException
{
try {
byte[] decoded = transportDetails.getDecodedMessage(message.getMessageBody().getBytes());
SignalMessage signalMessage = new SignalMessage(decoded);
SessionCipher sessionCipher = new SessionCipher(signalProtocolStore, new SignalProtocolAddress(message.getSender(), 1));
byte[] padded = sessionCipher.decrypt(signalMessage);
byte[] plaintext = transportDetails.getStrippedPaddingMessageBody(padded);
if (message.isEndSession() && "TERMINATE".equals(new String(plaintext))) {
signalProtocolStore.deleteSession(new SignalProtocolAddress(message.getSender(), 1));
}
return message.withMessageBody(new String(plaintext));
} catch (IOException | IllegalArgumentException | NullPointerException e) {
throw new InvalidMessageException(e);
}
}
示例2
public IncomingEncryptedMessage decrypt(Context context, IncomingPreKeyBundleMessage message)
throws InvalidVersionException, InvalidMessageException, DuplicateMessageException,
UntrustedIdentityException, LegacyMessageException
{
try {
byte[] decoded = transportDetails.getDecodedMessage(message.getMessageBody().getBytes());
PreKeySignalMessage preKeyMessage = new PreKeySignalMessage(decoded);
SessionCipher sessionCipher = new SessionCipher(signalProtocolStore, new SignalProtocolAddress(message.getSender(), 1));
byte[] padded = sessionCipher.decrypt(preKeyMessage);
byte[] plaintext = transportDetails.getStrippedPaddingMessageBody(padded);
return new IncomingEncryptedMessage(message, new String(plaintext));
} catch (IOException | InvalidKeyException | InvalidKeyIdException e) {
throw new InvalidMessageException(e);
}
}
示例3
public OutgoingKeyExchangeMessage process(Context context, IncomingKeyExchangeMessage message)
throws UntrustedIdentityException, StaleKeyExchangeException,
InvalidVersionException, LegacyMessageException, InvalidMessageException
{
try {
Recipients recipients = RecipientFactory.getRecipientsFromString(context, message.getSender(), false);
SignalProtocolAddress signalProtocolAddress = new SignalProtocolAddress(message.getSender(), 1);
KeyExchangeMessage exchangeMessage = new KeyExchangeMessage(transportDetails.getDecodedMessage(message.getMessageBody().getBytes()));
SessionBuilder sessionBuilder = new SessionBuilder(signalProtocolStore, signalProtocolAddress);
KeyExchangeMessage response = sessionBuilder.process(exchangeMessage);
if (response != null) {
byte[] serializedResponse = transportDetails.getEncodedMessage(response.serialize());
return new OutgoingKeyExchangeMessage(recipients, new String(serializedResponse), message.getSubscriptionId());
} else {
return null;
}
} catch (IOException | InvalidKeyException e) {
throw new InvalidMessageException(e);
}
}
示例4
public void testNoSession() throws InvalidMessageException, LegacyMessageException, NoSessionException, DuplicateMessageException {
InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore();
InMemorySenderKeyStore bobStore = new InMemorySenderKeyStore();
GroupSessionBuilder aliceSessionBuilder = new GroupSessionBuilder(aliceStore);
GroupSessionBuilder bobSessionBuilder = new GroupSessionBuilder(bobStore);
GroupCipher aliceGroupCipher = new GroupCipher(aliceStore, GROUP_SENDER);
GroupCipher bobGroupCipher = new GroupCipher(bobStore, GROUP_SENDER);
SenderKeyDistributionMessage sentAliceDistributionMessage = aliceSessionBuilder.create(GROUP_SENDER);
SenderKeyDistributionMessage receivedAliceDistributionMessage = new SenderKeyDistributionMessage(sentAliceDistributionMessage.serialize());
// bobSessionBuilder.process(GROUP_SENDER, receivedAliceDistributionMessage);
byte[] ciphertextFromAlice = aliceGroupCipher.encrypt("smert ze smert".getBytes());
try {
byte[] plaintextFromAlice = bobGroupCipher.decrypt(ciphertextFromAlice);
throw new AssertionError("Should be no session!");
} catch (NoSessionException e) {
// good
}
}
示例5
public void testBasicEncryptDecrypt()
throws LegacyMessageException, DuplicateMessageException, InvalidMessageException, NoSessionException
{
InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore();
InMemorySenderKeyStore bobStore = new InMemorySenderKeyStore();
GroupSessionBuilder aliceSessionBuilder = new GroupSessionBuilder(aliceStore);
GroupSessionBuilder bobSessionBuilder = new GroupSessionBuilder(bobStore);
GroupCipher aliceGroupCipher = new GroupCipher(aliceStore, GROUP_SENDER);
GroupCipher bobGroupCipher = new GroupCipher(bobStore, GROUP_SENDER);
SenderKeyDistributionMessage sentAliceDistributionMessage = aliceSessionBuilder.create(GROUP_SENDER);
SenderKeyDistributionMessage receivedAliceDistributionMessage = new SenderKeyDistributionMessage(sentAliceDistributionMessage.serialize());
bobSessionBuilder.process(GROUP_SENDER, receivedAliceDistributionMessage);
byte[] ciphertextFromAlice = aliceGroupCipher.encrypt("smert ze smert".getBytes());
byte[] plaintextFromAlice = bobGroupCipher.decrypt(ciphertextFromAlice);
assertTrue(new String(plaintextFromAlice).equals("smert ze smert"));
}
示例6
public void testLargeMessages() throws InvalidMessageException, LegacyMessageException, NoSessionException, DuplicateMessageException {
InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore();
InMemorySenderKeyStore bobStore = new InMemorySenderKeyStore();
GroupSessionBuilder aliceSessionBuilder = new GroupSessionBuilder(aliceStore);
GroupSessionBuilder bobSessionBuilder = new GroupSessionBuilder(bobStore);
GroupCipher aliceGroupCipher = new GroupCipher(aliceStore, GROUP_SENDER);
GroupCipher bobGroupCipher = new GroupCipher(bobStore, GROUP_SENDER);
SenderKeyDistributionMessage sentAliceDistributionMessage = aliceSessionBuilder.create(GROUP_SENDER);
SenderKeyDistributionMessage receivedAliceDistributionMessage = new SenderKeyDistributionMessage(sentAliceDistributionMessage.serialize());
bobSessionBuilder.process(GROUP_SENDER, receivedAliceDistributionMessage);
byte[] plaintext = new byte[1024 * 1024];
new Random().nextBytes(plaintext);
byte[] ciphertextFromAlice = aliceGroupCipher.encrypt(plaintext);
byte[] plaintextFromAlice = bobGroupCipher.decrypt(ciphertextFromAlice);
assertTrue(Arrays.equals(plaintext, plaintextFromAlice));
}
示例7
private byte[] decrypt(SignalServiceProtos.Envelope envelope, byte[] ciphertext)
throws InvalidVersionException, InvalidMessageException, InvalidKeyException,
DuplicateMessageException, InvalidKeyIdException, UntrustedIdentityException,
LegacyMessageException, NoSessionException
{
SignalProtocolAddress sourceAddress = new SignalProtocolAddress(envelope.getSource(), envelope.getSourceDevice());
SessionCipher sessionCipher = new SessionCipher(signalProtocolStore, sourceAddress);
byte[] paddedMessage;
if (envelope.getType() == Type.PREKEY_BUNDLE) {
paddedMessage = sessionCipher.decrypt(new PreKeySignalMessage(ciphertext));
//纠正remote register id
SessionRecord sessionRecord = signalProtocolStore.loadSession(sourceAddress);
if (sessionRecord.getSessionState().getRemoteRegistrationId() == 0) {
sessionRecord.getSessionState().setRemoteRegistrationId(envelope.getSourceRegistration());
signalProtocolStore.storeSession(sourceAddress, sessionRecord);
}
} else if (envelope.getType() == Type.CIPHERTEXT) {
paddedMessage = sessionCipher.decrypt(new SignalMessage(ciphertext));
} else {
throw new InvalidMessageException("Unknown type: " + envelope.getType());
}
PushTransportDetails transportDetails = new PushTransportDetails(sessionCipher.getSessionVersion());
return transportDetails.getStrippedPaddingMessageBody(paddedMessage);
}
示例8
public KeyExchangeMessage(byte[] serialized)
throws InvalidMessageException, InvalidVersionException, LegacyMessageException
{
try {
byte[][] parts = ByteUtil.split(serialized, 1, serialized.length - 1);
this.version = ByteUtil.highBitsToInt(parts[0][0]);
this.supportedVersion = ByteUtil.lowBitsToInt(parts[0][0]);
if (this.version < CiphertextMessage.CURRENT_VERSION) {
throw new LegacyMessageException("Unsupported legacy version: " + this.version);
}
if (this.version > CiphertextMessage.CURRENT_VERSION) {
throw new InvalidVersionException("Unknown version: " + this.version);
}
SignalProtos.KeyExchangeMessage message = SignalProtos.KeyExchangeMessage.parseFrom(parts[1]);
if (!message.hasId() || !message.hasBaseKey() ||
!message.hasRatchetKey() || !message.hasIdentityKey() ||
!message.hasBaseKeySignature())
{
throw new InvalidMessageException("Some required fields missing!");
}
this.sequence = message.getId() >> 5;
this.flags = message.getId() & 0x1f;
this.serialized = serialized;
this.baseKey = Curve.decodePoint(message.getBaseKey().toByteArray(), 0);
this.baseKeySignature = message.getBaseKeySignature().toByteArray();
this.ratchetKey = Curve.decodePoint(message.getRatchetKey().toByteArray(), 0);
this.identityKey = new IdentityKey(message.getIdentityKey().toByteArray(), 0);
} catch (InvalidKeyException | IOException e) {
throw new InvalidMessageException(e);
}
}
示例9
private void handleSecureMessage(MasterSecret masterSecret, long messageId, long threadId,
IncomingTextMessage message)
throws NoSessionException, DuplicateMessageException,
InvalidMessageException, LegacyMessageException,
UntrustedIdentityException
{
EncryptingSmsDatabase database = DatabaseFactory.getEncryptingSmsDatabase(context);
SmsCipher cipher = new SmsCipher(new SilenceSignalProtocolStore(context, masterSecret, message.getSubscriptionId()));
IncomingTextMessage plaintext = cipher.decrypt(context, message);
database.updateMessageBody(masterSecret, messageId, plaintext.getMessageBody());
if (message.isEndSession()) SecurityEvent.broadcastSecurityUpdateEvent(context, threadId);
}
示例10
private void handleXmppExchangeMessage(MasterSecret masterSecret, long messageId, long threadId,
IncomingXmppExchangeMessage message)
throws NoSessionException, DuplicateMessageException, InvalidMessageException, LegacyMessageException
{
EncryptingSmsDatabase database = DatabaseFactory.getEncryptingSmsDatabase(context);
database.markAsXmppExchange(messageId);
}
示例11
/**
* Decrypt a SenderKey group message.
*
* @param senderKeyMessageBytes The received ciphertext.
* @param callback A callback that is triggered after decryption is complete,
* but before the updated session state has been committed to the session
* DB. This allows some implementations to store the committed plaintext
* to a DB first, in case they are concerned with a crash happening between
* the time the session state is updated but before they're able to store
* the plaintext to disk.
* @return Plaintext
* @throws LegacyMessageException
* @throws InvalidMessageException
* @throws DuplicateMessageException
*/
public byte[] decrypt(byte[] senderKeyMessageBytes, DecryptionCallback callback)
throws LegacyMessageException, InvalidMessageException, DuplicateMessageException,
NoSessionException
{
synchronized (LOCK) {
try {
SenderKeyRecord record = senderKeyStore.loadSenderKey(senderKeyId);
if (record.isEmpty()) {
throw new NoSessionException("No sender key for: " + senderKeyId);
}
SenderKeyMessage senderKeyMessage = new SenderKeyMessage(senderKeyMessageBytes);
SenderKeyState senderKeyState = record.getSenderKeyState(senderKeyMessage.getKeyId());
senderKeyMessage.verifySignature(senderKeyState.getSigningKeyPublic());
SenderMessageKey senderKey = getSenderKey(senderKeyState, senderKeyMessage.getIteration());
byte[] plaintext = getPlainText(senderKey.getIv(), senderKey.getCipherKey(), senderKeyMessage.getCipherText());
callback.handlePlaintext(plaintext);
senderKeyStore.storeSenderKey(senderKeyId, record);
return plaintext;
} catch (org.whispersystems.libsignal.InvalidKeyException | InvalidKeyIdException e) {
throw new InvalidMessageException(e);
}
}
}
示例12
public SenderKeyDistributionMessage(byte[] serialized) throws LegacyMessageException, InvalidMessageException {
try {
byte[][] messageParts = ByteUtil.split(serialized, 1, serialized.length - 1);
byte version = messageParts[0][0];
byte[] message = messageParts[1];
if (ByteUtil.highBitsToInt(version) < CiphertextMessage.CURRENT_VERSION) {
throw new LegacyMessageException("Legacy message: " + ByteUtil.highBitsToInt(version));
}
if (ByteUtil.highBitsToInt(version) > CURRENT_VERSION) {
throw new InvalidMessageException("Unknown version: " + ByteUtil.highBitsToInt(version));
}
SignalProtos.SenderKeyDistributionMessage distributionMessage = SignalProtos.SenderKeyDistributionMessage.parseFrom(message);
if (!distributionMessage.hasId() ||
!distributionMessage.hasIteration() ||
!distributionMessage.hasChainKey() ||
!distributionMessage.hasSigningKey())
{
throw new InvalidMessageException("Incomplete message.");
}
this.serialized = serialized;
this.id = distributionMessage.getId();
this.iteration = distributionMessage.getIteration();
this.chainKey = distributionMessage.getChainKey().toByteArray();
this.signatureKey = Curve.decodePoint(distributionMessage.getSigningKey().toByteArray(), 0);
} catch (InvalidProtocolBufferException | InvalidKeyException e) {
throw new InvalidMessageException(e);
}
}
示例13
public PreKeySignalMessage(byte[] serialized)
throws InvalidMessageException, InvalidVersionException
{
try {
this.version = ByteUtil.highBitsToInt(serialized[0]);
if (this.version > CiphertextMessage.CURRENT_VERSION) {
throw new InvalidVersionException("Unknown version: " + this.version);
}
if (this.version < CiphertextMessage.CURRENT_VERSION) {
throw new LegacyMessageException("Legacy version: " + this.version);
}
SignalProtos.PreKeySignalMessage preKeyWhisperMessage
= SignalProtos.PreKeySignalMessage.parseFrom(ByteString.copyFrom(serialized, 1,
serialized.length-1));
if (!preKeyWhisperMessage.hasSignedPreKeyId() ||
!preKeyWhisperMessage.hasBaseKey() ||
!preKeyWhisperMessage.hasIdentityKey() ||
!preKeyWhisperMessage.hasMessage())
{
throw new InvalidMessageException("Incomplete message.");
}
this.serialized = serialized;
this.registrationId = preKeyWhisperMessage.getRegistrationId();
this.preKeyId = preKeyWhisperMessage.hasPreKeyId() ? Optional.of(preKeyWhisperMessage.getPreKeyId()) : Optional.<Integer>absent();
this.signedPreKeyId = preKeyWhisperMessage.hasSignedPreKeyId() ? preKeyWhisperMessage.getSignedPreKeyId() : -1;
this.baseKey = Curve.decodePoint(preKeyWhisperMessage.getBaseKey().toByteArray(), 0);
this.identityKey = new IdentityKey(Curve.decodePoint(preKeyWhisperMessage.getIdentityKey().toByteArray(), 0));
this.message = new SignalMessage(preKeyWhisperMessage.getMessage().toByteArray());
} catch (InvalidProtocolBufferException | InvalidKeyException | LegacyMessageException e) {
throw new InvalidMessageException(e);
}
}
示例14
public SenderKeyMessage(byte[] serialized) throws InvalidMessageException, LegacyMessageException {
try {
byte[][] messageParts = ByteUtil.split(serialized, 1, serialized.length - 1 - SIGNATURE_LENGTH, SIGNATURE_LENGTH);
byte version = messageParts[0][0];
byte[] message = messageParts[1];
byte[] signature = messageParts[2];
if (ByteUtil.highBitsToInt(version) < 3) {
throw new LegacyMessageException("Legacy message: " + ByteUtil.highBitsToInt(version));
}
if (ByteUtil.highBitsToInt(version) > CURRENT_VERSION) {
throw new InvalidMessageException("Unknown version: " + ByteUtil.highBitsToInt(version));
}
SignalProtos.SenderKeyMessage senderKeyMessage = SignalProtos.SenderKeyMessage.parseFrom(message);
if (!senderKeyMessage.hasId() ||
!senderKeyMessage.hasIteration() ||
!senderKeyMessage.hasCiphertext())
{
throw new InvalidMessageException("Incomplete message.");
}
this.serialized = serialized;
this.messageVersion = ByteUtil.highBitsToInt(version);
this.keyId = senderKeyMessage.getId();
this.iteration = senderKeyMessage.getIteration();
this.ciphertext = senderKeyMessage.getCiphertext().toByteArray();
} catch (InvalidProtocolBufferException | ParseException e) {
throw new InvalidMessageException(e);
}
}
示例15
public SignalMessage(byte[] serialized) throws InvalidMessageException, LegacyMessageException {
try {
byte[][] messageParts = ByteUtil.split(serialized, 1, serialized.length - 1 - MAC_LENGTH, MAC_LENGTH);
byte version = messageParts[0][0];
byte[] message = messageParts[1];
byte[] mac = messageParts[2];
if (ByteUtil.highBitsToInt(version) < CURRENT_VERSION) {
throw new LegacyMessageException("Legacy message: " + ByteUtil.highBitsToInt(version));
}
if (ByteUtil.highBitsToInt(version) > CURRENT_VERSION) {
throw new InvalidMessageException("Unknown version: " + ByteUtil.highBitsToInt(version));
}
SignalProtos.SignalMessage whisperMessage = SignalProtos.SignalMessage.parseFrom(message);
if (!whisperMessage.hasCiphertext() ||
!whisperMessage.hasCounter() ||
!whisperMessage.hasRatchetKey())
{
throw new InvalidMessageException("Incomplete message.");
}
this.serialized = serialized;
this.senderRatchetKey = Curve.decodePoint(whisperMessage.getRatchetKey().toByteArray(), 0);
this.messageVersion = ByteUtil.highBitsToInt(version);
this.counter = whisperMessage.getCounter();
this.previousCounter = whisperMessage.getPreviousCounter();
this.ciphertext = whisperMessage.getCiphertext().toByteArray();
} catch (InvalidProtocolBufferException | InvalidKeyException | ParseException e) {
throw new InvalidMessageException(e);
}
}
示例16
public void testOutOfOrder()
throws LegacyMessageException, DuplicateMessageException, InvalidMessageException, NoSessionException
{
InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore();
InMemorySenderKeyStore bobStore = new InMemorySenderKeyStore();
GroupSessionBuilder aliceSessionBuilder = new GroupSessionBuilder(aliceStore);
GroupSessionBuilder bobSessionBuilder = new GroupSessionBuilder(bobStore);
SenderKeyName aliceName = GROUP_SENDER;
GroupCipher aliceGroupCipher = new GroupCipher(aliceStore, aliceName);
GroupCipher bobGroupCipher = new GroupCipher(bobStore, aliceName);
SenderKeyDistributionMessage aliceDistributionMessage =
aliceSessionBuilder.create(aliceName);
bobSessionBuilder.process(aliceName, aliceDistributionMessage);
ArrayList<byte[]> ciphertexts = new ArrayList<>(100);
for (int i=0;i<100;i++) {
ciphertexts.add(aliceGroupCipher.encrypt("up the punks".getBytes()));
}
while (ciphertexts.size() > 0) {
int index = randomInt() % ciphertexts.size();
byte[] ciphertext = ciphertexts.remove(index);
byte[] plaintext = bobGroupCipher.decrypt(ciphertext);
assertTrue(new String(plaintext).equals("up the punks"));
}
}
示例17
public void testTooFarInFuture() throws DuplicateMessageException, InvalidMessageException, LegacyMessageException, NoSessionException {
InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore();
InMemorySenderKeyStore bobStore = new InMemorySenderKeyStore();
GroupSessionBuilder aliceSessionBuilder = new GroupSessionBuilder(aliceStore);
GroupSessionBuilder bobSessionBuilder = new GroupSessionBuilder(bobStore);
SenderKeyName aliceName = GROUP_SENDER;
GroupCipher aliceGroupCipher = new GroupCipher(aliceStore, aliceName);
GroupCipher bobGroupCipher = new GroupCipher(bobStore, aliceName);
SenderKeyDistributionMessage aliceDistributionMessage = aliceSessionBuilder.create(aliceName);
bobSessionBuilder.process(aliceName, aliceDistributionMessage);
for (int i=0;i<2001;i++) {
aliceGroupCipher.encrypt("up the punks".getBytes());
}
byte[] tooFarCiphertext = aliceGroupCipher.encrypt("notta gonna worka".getBytes());
try {
bobGroupCipher.decrypt(tooFarCiphertext);
throw new AssertionError("Should have failed!");
} catch (InvalidMessageException e) {
// good
}
}
示例18
private void storeRetrievedMms(MasterSecret masterSecret, String contentLocation,
long messageId, long threadId, EncodedStringValue pduFrom,
EncodedStringValue[] pduTo, EncodedStringValue[] pduCc, PduBody pduBody,
long date, boolean isSecure, int subscriptionId)
throws MmsException, NoSessionException, DuplicateMessageException, InvalidMessageException,
LegacyMessageException
{
MmsDatabase database = DatabaseFactory.getMmsDatabase(context);
SingleUseBlobProvider provider = SingleUseBlobProvider.getInstance();
String from = null;
List<String> to = new LinkedList<>();
List<String> cc = new LinkedList<>();
String body = null;
List<Attachment> attachments = new LinkedList<>();
if (pduFrom != null) {
from = Util.toIsoString(pduFrom.getTextString());
}
if (pduTo != null) {
for (EncodedStringValue toValue : pduTo) {
to.add(Util.toIsoString(toValue.getTextString()));
}
}
if (pduCc != null) {
for (EncodedStringValue ccValue : pduCc) {
cc.add(Util.toIsoString(ccValue.getTextString()));
}
}
if (pduBody != null) {
body = PartParser.getMessageText(pduBody);
PduBody media = PartParser.getSupportedMediaParts(pduBody);
for (int i=0;i<media.getPartsNum();i++) {
PduPart part = media.getPart(i);
if (part.getData() != null) {
byte[] decodedDigest = null;
if (isSecure) {
PduPart digestPart = pduBody.getPartByName(Util.toIsoString(part.getName()) + ".digest");
byte[] digestBytes = null;
if (digestPart != null) {
digestBytes = digestPart.getData();
}
if (digestBytes != null) {
decodedDigest = Base64.decode(digestBytes, Base64.NO_WRAP);
}
if (decodedDigest != null) {
Log.w(TAG, "Available digest for part name " + Util.toIsoString(part.getName()) + " (content id " + Util.toIsoString(part.getContentId()) + "): " + Hex.toString(decodedDigest));
} else {
Log.w(TAG, "No available digest for part name " + Util.toIsoString(part.getName()) + " (content id " + Util.toIsoString(part.getContentId()) + ")");
}
}
Uri uri = provider.createUri(part.getData());
attachments.add(new UriAttachment(uri, Util.toIsoString(part.getContentType()),
AttachmentDatabase.TRANSFER_PROGRESS_DONE,
part.getData().length, decodedDigest));
}
}
}
IncomingMediaMessage message = new IncomingMediaMessage(from, to, cc, body, date * 1000L, attachments, subscriptionId);
Pair<Long, Long> messageAndThreadId;
if (isSecure) {
messageAndThreadId = database.insertSecureDecryptedMessageInbox(masterSecret, message,
threadId);
} else {
messageAndThreadId = database.insertMessageInbox(masterSecret, message,
contentLocation, threadId);
}
database.delete(messageId);
MessageNotifier.updateNotification(context, masterSecret, message.getSubscriptionId());
}
示例19
public void testBasicRatchet()
throws LegacyMessageException, DuplicateMessageException, InvalidMessageException, NoSessionException
{
InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore();
InMemorySenderKeyStore bobStore = new InMemorySenderKeyStore();
GroupSessionBuilder aliceSessionBuilder = new GroupSessionBuilder(aliceStore);
GroupSessionBuilder bobSessionBuilder = new GroupSessionBuilder(bobStore);
SenderKeyName aliceName = GROUP_SENDER;
GroupCipher aliceGroupCipher = new GroupCipher(aliceStore, aliceName);
GroupCipher bobGroupCipher = new GroupCipher(bobStore, aliceName);
SenderKeyDistributionMessage sentAliceDistributionMessage =
aliceSessionBuilder.create(aliceName);
SenderKeyDistributionMessage receivedAliceDistributionMessage =
new SenderKeyDistributionMessage(sentAliceDistributionMessage.serialize());
bobSessionBuilder.process(aliceName, receivedAliceDistributionMessage);
byte[] ciphertextFromAlice = aliceGroupCipher.encrypt("smert ze smert".getBytes());
byte[] ciphertextFromAlice2 = aliceGroupCipher.encrypt("smert ze smert2".getBytes());
byte[] ciphertextFromAlice3 = aliceGroupCipher.encrypt("smert ze smert3".getBytes());
byte[] plaintextFromAlice = bobGroupCipher.decrypt(ciphertextFromAlice);
try {
bobGroupCipher.decrypt(ciphertextFromAlice);
throw new AssertionError("Should have ratcheted forward!");
} catch (DuplicateMessageException dme) {
// good
}
byte[] plaintextFromAlice2 = bobGroupCipher.decrypt(ciphertextFromAlice2);
byte[] plaintextFromAlice3 = bobGroupCipher.decrypt(ciphertextFromAlice3);
assertTrue(new String(plaintextFromAlice).equals("smert ze smert"));
assertTrue(new String(plaintextFromAlice2).equals("smert ze smert2"));
assertTrue(new String(plaintextFromAlice3).equals("smert ze smert3"));
}
示例20
public void testLateJoin() throws NoSessionException, InvalidMessageException, LegacyMessageException, DuplicateMessageException {
InMemorySenderKeyStore aliceStore = new InMemorySenderKeyStore();
InMemorySenderKeyStore bobStore = new InMemorySenderKeyStore();
GroupSessionBuilder aliceSessionBuilder = new GroupSessionBuilder(aliceStore);
SenderKeyName aliceName = GROUP_SENDER;
GroupCipher aliceGroupCipher = new GroupCipher(aliceStore, aliceName);
SenderKeyDistributionMessage aliceDistributionMessage = aliceSessionBuilder.create(aliceName);
// Send off to some people.
for (int i=0;i<100;i++) {
aliceGroupCipher.encrypt("up the punks up the punks up the punks".getBytes());
}
// Now Bob Joins.
GroupSessionBuilder bobSessionBuilder = new GroupSessionBuilder(bobStore);
GroupCipher bobGroupCipher = new GroupCipher(bobStore, aliceName);
SenderKeyDistributionMessage distributionMessageToBob = aliceSessionBuilder.create(aliceName);
bobSessionBuilder.process(aliceName, new SenderKeyDistributionMessage(distributionMessageToBob.serialize()));
byte[] ciphertext = aliceGroupCipher.encrypt("welcome to the group".getBytes());
byte[] plaintext = bobGroupCipher.decrypt(ciphertext);
assertEquals(new String(plaintext), "welcome to the group");
}
示例21
/**
* Decrypt a SenderKey group message.
*
* @param senderKeyMessageBytes The received ciphertext.
* @return Plaintext
* @throws LegacyMessageException
* @throws InvalidMessageException
* @throws DuplicateMessageException
*/
public byte[] decrypt(byte[] senderKeyMessageBytes)
throws LegacyMessageException, DuplicateMessageException, InvalidMessageException, NoSessionException
{
return decrypt(senderKeyMessageBytes, new NullDecryptionCallback());
}