/// <summary> /// Decrypts the specified message. /// </summary> /// <param name="Message">The message.</param> public byte[] Decrypt(Packet Message) { byte[] EncryptedData = Message.Payload.ToArray(); byte[] DecryptedData = null; if (Message.Identifier == 24112) { Message.Identifier = 0; } if (this.ReceiveEncrypter1 == null) { if (this.PepperState == 0) { if (Message.Identifier == 10100) { DecryptedData = PepperCrypto.PepperAuthentification(EncryptedData); } } else { switch (this.PepperState) { case 1: { DecryptedData = PepperCrypto.PepperAuthentificationResponseOpen(EncryptedData); if (Message.Identifier == 20100) { int KeyL = DecryptedData[0] << 24 | DecryptedData[1] << 16 | DecryptedData[2] << 8 | DecryptedData[3]; if (KeyL != 24) { Logging.Error(this.GetType(), "Decrypt() - Session key length is not valid. (" + KeyL + ")"); } Array.Copy(DecryptedData, 4, this.SessionKey = new byte[KeyL], 0, KeyL); } break; } case 2: { if (Message.Identifier == 10101) { DecryptedData = PepperCrypto.PepperLoginOpen(PepperFactory.ServerPublicKey, PepperFactory.ServerSecretKey, this.SessionKey, ref this.ClientPublicKey, ref this.ClientNonce, EncryptedData); } else { goto default; } break; } case 3: { if (Message.Destination == Destination.FROM_SERVER) { DecryptedData = PepperCrypto.PepperLoginResponseOpen(this.ClientNonce, this.ProxyPublicKey, PepperFactory.SupercellServerPublicKey, this.ProxySecretKey, ref this.ServerNonce, ref this.SecretKey, EncryptedData); this.ReceiveEncrypter1 = new PepperEncrypter(this.ClientNonce, this.SecretKey); this.ReceiveEncrypter2 = new PepperEncrypter(this.ServerNonce, this.SecretKey); } else { goto default; } break; } default: { DecryptedData = EncryptedData; break; } } } } else { if (Message.Destination == Destination.FROM_CLIENT) { DecryptedData = this.ReceiveEncrypter1.Decrypt(EncryptedData); } else { DecryptedData = this.ReceiveEncrypter2.Decrypt(EncryptedData); } } return(DecryptedData); }
/// <summary> /// Encrypts the specified message. /// </summary> /// <param name="Message">The message.</param> public byte[] Encrypt(Packet Message) { byte[] DecryptedData = Message.Decrypted_Data.ToArray(); byte[] EncryptedData = Message.Decrypted_Data.ToArray(); if (this.SendEncrypter1 == null) { if (this.PepperState == 0) { if (Message.Identifier == 10100) { ++this.PepperState; EncryptedData = PepperCrypto.PepperAuthentification(EncryptedData); } } else { switch (this.PepperState) { case 1: { this.PepperState = 2; EncryptedData = PepperCrypto.PepperAuthentificationResponse(EncryptedData); break; } case 2: { if (Message.Identifier == 10101) { this.PepperState = 3; EncryptedData = PepperCrypto.PepperLogin(PepperFactory.SupercellServerPublicKey, this.ProxySecretKey, this.ProxyPublicKey, this.SessionKey, this.ClientNonce, DecryptedData); } else { goto default; } break; } case 3: { if (Message.Destination == Destination.FROM_SERVER) { this.PepperState = -1; EncryptedData = PepperCrypto.PepperLoginResponse(this.ClientNonce, PepperFactory.ServerPublicKey, this.ClientPublicKey, PepperFactory.ServerSecretKey, this.ServerNonce, this.SecretKey, DecryptedData); this.SendEncrypter1 = new PepperEncrypter(this.ClientNonce, this.SecretKey); this.SendEncrypter2 = new PepperEncrypter(this.ServerNonce, this.SecretKey); } else { goto default; } break; } default: { EncryptedData = DecryptedData; break; } } } } else { if (Message.Destination == Destination.FROM_CLIENT) { EncryptedData = this.SendEncrypter1.Encrypt(DecryptedData); } else { EncryptedData = this.SendEncrypter2.Encrypt(DecryptedData); } } return(EncryptedData); }
internal static byte[] PepperLoginOpen(byte[] BlakePublicKey, byte[] BoxSecretKey, byte[] AuthSessionKey, ref byte[] BoxPublicKey, ref byte[] OutNonce, byte[] Data) { if (Data.Length >= 32) { Array.Copy(Data, BoxPublicKey = new byte[32], 32); Blake2BHasher Blake2B = new Blake2BHasher(); Blake2B.Update(BoxPublicKey); Blake2B.Update(BlakePublicKey); byte[] c = new byte[16].Concat(Data.Skip(32)).ToArray(); if (curve25519xsalsa20poly1305.crypto_box_afternm(c, c, Blake2B.Finish(), PepperCrypto.SecretKey(BoxPublicKey, BoxSecretKey)) == 0) { byte[] SessionKey = new byte[24]; byte[] Decrypted = new byte[c.Length - 32 - 48]; Array.Copy(c, 32, SessionKey, 0, 24); Array.Copy(c, 32 + 24, OutNonce = new byte[24], 0, 24); Array.Copy(c, 32 + 48, Decrypted, 0, Decrypted.Length); for (int i = 0; i < 24; i++) { if (SessionKey[i] != AuthSessionKey[i]) { Logging.Error(typeof(PepperCrypto), "PepperLoginOpen() - Unable to decrypt pepper login. SessionKey != AuthSessionKey."); return(null); } } return(Decrypted); } Logging.Error(typeof(PepperCrypto), "PepperLoginOpen() - Unable to decrypt pepper login. curve25519xsalsa20poly1305.crypto_box_afternm != 0."); } return(null); }
internal static byte[] PepperLogin(byte[] BoxPublicKey, byte[] BoxSecretKey, byte[] BlakePublicKey, byte[] AuthSessionKey, byte[] OutNonce, byte[] Data) { byte[] c = new byte[Data.Length + 32 + 24 + 24]; Array.Copy(AuthSessionKey, 0, c, 32, 24); Array.Copy(OutNonce, 0, c, 32 + 24, 24); Array.Copy(Data, 0, c, 32 + 48, Data.Length); Blake2BHasher Blake2B = new Blake2BHasher(); Blake2B.Update(BlakePublicKey); Blake2B.Update(BoxPublicKey); if (curve25519xsalsa20poly1305.crypto_box_afternm(c, c, Blake2B.Finish(), PepperCrypto.SecretKey(BoxPublicKey, BoxSecretKey)) == 0) { byte[] Encrypted = new byte[c.Length - 16 + 32]; Array.Copy(BlakePublicKey, 0, Encrypted, 0, 32); Array.Copy(c, 16, Encrypted, 32, c.Length - 16); return(Encrypted); } Logging.Error(typeof(PepperCrypto), "PepperLogin() - Unable to encrypt pepper login. curve25519xsalsa20poly1305.crypto_box_afternm != 0"); return(null); }
internal static byte[] PepperLoginResponseOpen(byte[] BlakeNonce, byte[] BlakePublicKey, byte[] BoxPublicKey, byte[] BoxSecretKey, ref byte[] OutNonce, ref byte[] OutKey, byte[] Data) { Blake2BHasher Blake2B = new Blake2BHasher(); Blake2B.Update(BlakeNonce); Blake2B.Update(BlakePublicKey); Blake2B.Update(BoxPublicKey); byte[] c = new byte[16].Concat(Data).ToArray(); if (curve25519xsalsa20poly1305.crypto_box_open_afternm(c, c, Blake2B.Finish(), PepperCrypto.SecretKey(BoxPublicKey, BoxSecretKey)) == 0) { byte[] Decrypted = new byte[c.Length - 32 - 32 - 24]; Array.Copy(c, 32, OutNonce = new byte[24], 0, 24); Array.Copy(c, 32 + 24, OutKey = new byte[32], 0, 32); Array.Copy(c, 32 + 24 + 32, Decrypted, 0, Decrypted.Length); return(Decrypted); } Logging.Error(typeof(PepperCrypto), "PepperLoginResponseOpen() - Unable de decrypt pepper login response. curve25519xsalsa20poly1305.crypto_box_open_afternm != 0"); return(null); }
/// <summary> /// Encryptes the login response message. /// </summary> internal static byte[] PepperLoginResponse(byte[] BlakeNonce, byte[] BlakePublicKey, byte[] BoxPublicKey, byte[] BoxSecretKey, byte[] OutNonce, byte[] OutKey, byte[] Data) { Blake2BHasher Blake2B = new Blake2BHasher(); Blake2B.Update(BlakeNonce); Blake2B.Update(BoxPublicKey); Blake2B.Update(BlakePublicKey); byte[] m = new byte[Data.Length + 88]; Array.Copy(OutNonce, 0, m, 32, 24); Array.Copy(OutKey, 0, m, 32 + 24, 32); Array.Copy(Data, 0, m, 32 + 24 + 32, Data.Length); if (curve25519xsalsa20poly1305.crypto_box_afternm(m, m, Blake2B.Finish(), PepperCrypto.SecretKey(BoxPublicKey, BoxSecretKey)) == 0) { byte[] Encrypted = new byte[m.Length - 16]; Buffer.BlockCopy(m, 16, Encrypted, 0, m.Length - 16); return(Encrypted); } Logging.Error(typeof(PepperCrypto), "PepperLoginResponse() - Unable de encrypt pepper login response. curve25519xsalsa20poly1305.crypto_box_afternm != 0"); return(null); }