W tym szyfrowaniu użyjemy tajnego klucza do zaszyfrowania ciągu. Zastosowanym algorytmem będzie AES z trybem CBC (Cipher Block Chaining).
Kod C# użyje dopełnienia PKCS7, ponieważ PKCS5 nie jest tam dostępny. W Androidzie używa wewnętrznie dopełnienia PKCS5, nawet jeśli określimy dopełnienie PKCS7 w transformacji szyfru. Tak więc określamy również tryb dopełniania PKCS5. Podczas testów oba dają te same prawidłowe wyniki.
W tej metodzie szyfrowania pojedynczy klucz jest używany zarówno jako klucz tajny, jak i sól.
Podczas używania różnych kluczy dla klucza tajnego i soli istniała pewna różnica między wersjami salt zakodowanymi Base64 (lub wektorem inicjującym). Wersje zakodowane w Base64 zostały utworzone przez kody Androida i C# i różniły się od siebie.
Aby temu zaradzić, użyliśmy jednego klucza, który będzie służył zarówno jako tajny klucz, jak i sól.
Kod części dla Androida wygląda następująco:
public class EncryptionUtils { prywatne końcowe String characterEncoding = "UTF-8"; private final String cipherTransformation = "AES/CBC/PKCS5Padding"; private final String aesEncryptionAlgorithm = "AES"; public String encrypt(String plainText, String key) generuje UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException { byte [] plainTextbytes = plainText.getBytes(characterEncoding); bajt [] keyBytes = getKeyBytes(klucz); // zwróć Base64.encodeToString(encrypt(plainTextbytes,keyBytes, keyBytes), Base64.DEFAULT); return Base64.encodeToString(encrypt(plainTextbytes,keyBytes, keyBytes), Base64.NO_WRAP); } public String decrypt(String zaszyfrowany tekst, klucz ciągu) zgłasza KeyException, GeneralSecurityException, GeneralSecurityException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, IOException { byte [] cipheredBytes = Base64.decode(encryptedText, Base64.DEFAULT); byte[] keyBytes = getKeyBytes(klucz); zwróć nowy String (decrypt(cipheredBytes, keyBytes, keyBytes), characterEncoding); } public byte [] decrypt( byte[] cipherText, byte[] key, byte [] initialVector) zgłasza NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException { Cipher Transcipher = Cipher.getInstance);(cipherTransformation); SecretKeySpec secretKeySpecy = new SecretKeySpec(key, aesEncryptionAlgorithm); IvParameterSpec ivParameterSpec = new IvParameterSpec(initialVector); cipher.init(Cipher.DECRYPT_MODE, secretKeySpecy, ivParameterSpec); tekst zaszyfrowany = cipher.doFinal(zaszyfrowany tekst); zwróć tekst zaszyfrowany; } public byte[] encrypt(byte[] plainText, byte[] key, byte [] initialVector) zgłasza NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException { Cipher cipher = Cipher.getInstance);(cipherTransformation); SecretKeySpec secretKeySpec = new SecretKeySpec(key, aesEncryptionAlgorithm); IvParameterSpec ivParameterSpec = new IvParameterSpec(initialVector); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); zwykły tekst = cipher.doFinal(zwykły tekst); return zwykły tekst; } private byte[] getKeyBytes(String key) wyrzuca UnsupportedEncodingException{ byte [] keyBytes= new byte[16]; byte [] parametrKeyBytes= key.getBytes(znakKodowanie); System .arraycopy(parameterKeyBytes, 0 , keyBytes, 0, Math.min(parameterKeyBytes.length, keyBytes.length)); zwróć keyBytes; } } Zalecana lektura: Skopiuj do schowka w JavaScript
Kod części C# wygląda następująco:
// Szyfruje zwykły tekst za pomocą 128-bitowego klucza AES i szyfru blokowego łańcuchowego oraz zwraca ciąg publiczny zakodowany w base64 Encrypt(String plainText, String key) { var plainBytes = Encoding.UTF8.GetBytes(plainText); return Convert.ToBase64String(Encrypt(plainBytes, GetRijndaelManaged(klucz))); } public string Decrypt(String zaszyfrowany tekst, String klucz) { var zaszyfrowanyBytes = Convert.FromBase64String(encryptedText); return Encoding.UTF8.GetString(Decrypt(encryptedBytes, GetRijndaelManaged(klucz))); } public byte[] Encrypt(byte[] plainBytes, RijndaelManaged rijndaelManaged) { return rijndaelManaged.CreateEncryptor() .TransformFinalBlock(plainBytes, 0, plainBytes.Length); } public byte[] Decrypt(byte[] cryptoData, RijndaelManaged rijndaelManaged) { return rijndaelManaged.CreateDecryptor() .TransformFinalBlock(encryptedData, 0, cryptoData.Length); } public RijndaelManaged GetRijndaelManaged(String secretKey) { var keyBytes = new byte[16]; var secretKeyBytes = Kodowanie.UTF8.GetBytes(secretKey); Array.Copy(secretKeyBytes, keyBytes, Math.Min(keyBytes.Length, secretKeyBytes.Length)); return new RijndaelManaged { Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7, KeySize = 128, BlockSize = 128, Key = keyBytes, IV = keyBytes }; }
Za pomocą powyższego kodu można zaszyfrować ciąg znaków na jednej platformie, a następnie odszyfrować go na drugiej platformie i odwrotnie.
Zalecane przeczytanie: Jak wyświetlić kod pliku „.ctp” tak kolorowy jak plik „.php” w NetBeans?