You did not provide much details about your use case, but I would say that this happens because you do not use the same encryption settings during encryption and decryption operations. Symmetric ciphers require that you use exactly the same parameters / parameters during data encryption, as well as decryption. For example, for AES CBC you will need to use the exact same key, IV, encryption mode and padding on both devices. It is best to set these settings in code:
System.Security.Cryptography.RijndaelManaged aes = new System.Security.Cryptography.RijndaelManaged(); aes.Key = new byte[] { ... }; aes.IV = new byte[] { ... }; aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.PKCS7;
If you are sure that you are using the same settings, you should also consider that some data is corrupted or changed during network transmission.
Edit after some code fragments have been provided:
The decryption method that you provided does not work for me at all, so I collected all of your samples and turned them into code that does the same as you, but uses IMO a slightly cleaner approach. For example, this code uses a more reliable "key output" (please forgive me cryptoguys), and it also went through a basic code analysis.
You should be able to easily use public methods to do what you need:
string plainData = "This information should be encrypted"; string encryptedData = EncryptStringified(plainData); string decryptedData = DecryptStringified(encryptedData); if (plainData != decryptedData) throw new Exception("Decryption failed");
Implementation and private methods:
/// <summary> /// Encrypts string with the key derived from device ID /// </summary> /// <returns>Base64 encoded encrypted data</returns> /// <param name="stringToEncrypt">String to encrypt</param> public string EncryptStringified(string stringToEncrypt) { if (stringToEncrypt == null) throw new ArgumentNullException("stringToEncrypt"); byte[] key = DeviceIdToDesKey(); byte[] plainData = Encoding.UTF8.GetBytes(stringToEncrypt); byte[] encryptedData = Encrypt(key, plainData); return Convert.ToBase64String(encryptedData); } /// <summary> /// Decrypts Base64 encoded data with the key derived from device ID /// </summary> /// <returns>Decrypted string</returns> /// <param name="b64DataToDecrypt">Base64 encoded data to decrypt</param> public string DecryptStringified(string b64DataToDecrypt) { if (b64DataToDecrypt == null) throw new ArgumentNullException("b64DataToDecrypt"); byte[] key = DeviceIdToDesKey(); byte[] encryptedData = Convert.FromBase64String(b64DataToDecrypt); byte[] decryptedData = Decrypt(key, encryptedData); return Encoding.UTF8.GetString(decryptedData); } private byte[] DeviceIdToDesKey() { TelephonyManager telephonyMgr = Application.Context.GetSystemService(Context.TelephonyService) as TelephonyManager; string deviceId = telephonyMgr.DeviceId ?? "UNAVAILABLE"; // Compute hash of device ID so we are sure enough bytes have been gathered for the key byte[] bytes = null; using (SHA1 sha1 = SHA1.Create()) bytes = sha1.ComputeHash(Encoding.UTF8.GetBytes(deviceId)); // Get last 8 bytes from device ID hash as a key byte[] desKey = new byte[8]; Array.Copy(bytes, bytes.Length - desKey.Length, desKey, 0, desKey.Length); return desKey; } private byte[] Encrypt(byte[] key, byte[] plainData) { if (key == null) throw new ArgumentNullException("key"); if (plainData == null) throw new ArgumentNullException("plainData"); using (DESCryptoServiceProvider desProvider = new DESCryptoServiceProvider()) { if (!desProvider.ValidKeySize(key.Length * 8)) throw new CryptographicException("Key with invalid size has been specified"); desProvider.Key = key; // desProvider.IV should be automatically filled with random bytes when DESCryptoServiceProvider instance is created desProvider.Mode = CipherMode.CBC; desProvider.Padding = PaddingMode.PKCS7; using (MemoryStream encryptedStream = new MemoryStream()) { // Write IV at the beginning of memory stream encryptedStream.Write(desProvider.IV, 0, desProvider.IV.Length); // Perform encryption and append encrypted data to the memory stream using (ICryptoTransform encryptor = desProvider.CreateEncryptor()) { byte[] encryptedData = encryptor.TransformFinalBlock(plainData, 0, plainData.Length); encryptedStream.Write(encryptedData, 0, encryptedData.Length); } return encryptedStream.ToArray(); } } } private byte[] Decrypt(byte[] key, byte[] encryptedData) { if (key == null) throw new ArgumentNullException("key"); if (encryptedData == null) throw new ArgumentNullException("encryptedData"); using (DESCryptoServiceProvider desProvider = new DESCryptoServiceProvider()) { if (!desProvider.ValidKeySize(key.Length * 8)) throw new CryptographicException("Key with invalid size has been specified"); desProvider.Key = key; if (encryptedData.Length <= desProvider.IV.Length) throw new CryptographicException("Too short encrypted data has been specified"); // Read IV from the beginning of encrypted data // Note: New byte array needs to be created because data written to desprovider.IV are ignored byte[] iv = new byte[desProvider.IV.Length]; Array.Copy(encryptedData, 0, iv, 0, iv.Length); desProvider.IV = iv; desProvider.Mode = CipherMode.CBC; desProvider.Padding = PaddingMode.PKCS7; // Remove IV from the beginning of encrypted data and perform decryption using (ICryptoTransform decryptor = desProvider.CreateDecryptor()) return decryptor.TransformFinalBlock(encryptedData, desProvider.IV.Length, encryptedData.Length - desProvider.IV.Length); } }
Itโs actually hard to say exactly what happened with your code because your decryption method did not work for me at all - most likely because it uses CryptoStream in write mode for decryption, which seems a little strange to me.
So much for the code. Now let me get the encryption, which is really very weak. It is rather just obfuscation, which should protect data from being accidentally displayed in text form (some use BASE64 encoding for the same thing). The main reason for this is the relatively old encryption algorithm and the easily predictable encryption key. AFAIK, each application running on the same device can read the device identifier without any privileges. This means that any application can decrypt your data. Of course, your SQLite database is probably only available for your application, but this can no longer be true if you remove the SD card or shorten your phone. To make this a little better, you could ask the user to provide a password and then use it to get a unique encryption key, but this is a completely different problem. In any case, I'm not quite sure what you are trying to achieve with this encryption - it can be completely sufficient for your needs, even if it can be considered weak.
Hope this helps.