2017-09-17 5 views
0

私はアンドリードコードを持っていて、それをC#に変換しようとしました。これは簡単な暗号化クラスです。しかし、それを使ってデータを解読しようとすると、私はキャッチします:Wrong algorithm: AES or Rijndael required。ここで 間違ったアルゴリズム:AESまたはRijndaelがCで必要です#

public static string decrypt(string data) 
{ 
    byte[] dataBytes = Convert.FromBase64String(data); 
    SecretKey secretKey = getSecretKey(hashTheKey("ABCD")); 

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 

    cipher.init(2, secretKey, new IvParameterSpec(new byte[16]), 
      SecureRandom.getInstance("SHA1PRNG")); 
    var x = cipher.doFinal(dataBytes); 
    return System.Text.Encoding.UTF8.GetString(x); 
} 
public static SecretKey getSecretKey(char[] key) 
{ 
    var secretKeyType = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
    var secretkey = secretKeyType.generateSecret(new PBEKeySpec(key, 
      System.Text.Encoding.UTF8 
       .GetBytes("ABCD"), 
      100, 128)).getEncoded(); 

    return new SecretKeySpec(secretkey, "AES/CBC/PKCS5Padding"); 
} 
public static char[] hashTheKey(string key) 
{ 
    MessageDigest messageDigest = MessageDigest.getInstance("SHA1"); 
    messageDigest.update(System.Text.Encoding.UTF8.GetBytes(key)); 
    return Convert.ToBase64String(messageDigest.digest()).ToCharArray(); 
} 

が私の元のアンドロイドコードです:
はここに私の変換されたコードである

private char[] hashTheKey(String key) throws UnsupportedEncodingException, NoSuchAlgorithmException { 
    MessageDigest messageDigest = MessageDigest.getInstance("SHA1"); 
    messageDigest.update(key.getBytes()); 
    return Base64.encodeToString(messageDigest.digest(), 
           Base64.NO_PADDING).toCharArray(); 
} 

private SecretKey getSecretKey(char[] key) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeySpecException { 
    return new SecretKeySpec(
     SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1") 
     .generateSecret(new PBEKeySpec(key, 
         "ABCD".getBytes("UTF8"), 
         100, 128)).getEncoded(), "AES"); 
} 

public String decrypt(String data) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException, InvalidKeySpecException { 
    byte[] dataBytes = Base64.decode(data, Base64.DEFAULT); 
    SecretKey secretKey = getSecretKey(hashTheKey("ABCD")); 
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    cipher.init(2, secretKey, new IvParameterSpec(new byte[16]), 
      SecureRandom.getInstance("SHA1PRNG")); 
    return new String(cipher.doFinal(dataBytes)); 
} 
+0

。 –

+0

私はそれを取得しません。それはそこに書く!変換されたコード。 – David

+0

'this.mBuilder.getAlgorithm()'はあなたのAndroidコードで何を返しますか? – algrid

答えて

1

0に以下のクラスを使用することができますようとは、よく確立された同じ暗号化アルゴリズムを使用していますが、呼び出す方法が異なります。しかし、まだコードを変換することは可能です。

重要な点は、base64エンコーディングの違いです - C#は常にパディングを使用します。

変換されたコードのようになります:あなたは、C#に変換しようとしている場合** ** C#のコードを投稿し、

const int KeySize = 128; 

static string HashTheKey(string key) { 
    String hashKey; 
    using (var sha = new SHA1Managed()) { 
    hashKey = Convert.ToBase64String(sha.ComputeHash(Encoding.UTF8.GetBytes(key))); 
    } 
    // beware - you're on C# now so remove the padding and add the newline to match java 
    return hashKey.Replace("=", "") + "\n"; 
} 

static byte[] GetSecretKey(string password) { 
    var salt = Encoding.UTF8.GetBytes("JVAaVhAiddKAaghraikhmaini"); 
    using (var pass = new Rfc2898DeriveBytes(password, salt, 65536)) { 
    return pass.GetBytes(KeySize/8); 
    } 
} 

static void Main(string[] args) { 
    string encrypted = "vtlkQHTz7/oz2weuAAkLz2Q5c2yj2LGukF7SHJjT+TA8oRLixTQSXQ7dG1O736hyT1HJxcz0P4DzzVaO5chWKKSJQ2uPEpDQJu/fZGguqDw="; 
    byte[] encryptedBytes = Convert.FromBase64String(encrypted); 
    using (var aes = new AesManaged()) { 
    aes.KeySize = KeySize; 
    aes.Padding = PaddingMode.PKCS7; 
    aes.Key = GetSecretKey(HashTheKey("Android")); 
    // you're using the same init vector in your android code 
    aes.IV = new byte[16]; 
    using (var decryptor = aes.CreateDecryptor()) { 
     // dumps {"barcode":"12345678","token":"cad603fc-1e53-4a95-9150-f1694baa07f9"} 
     Console.Out.WriteLine(Encoding.UTF8.GetString(decryptor.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length))); 
    } 
    } 
} 
-2

C#はAndroidやJavaなどの暗号化アルゴリズムを処理しませんが、AESまたはラインダールのいずれかのアルゴリズムを使用する必要がありませんあなたは、暗号化にBase64に単純なテキストに転化するエラーを見ることができますし、その逆もあなたは、C#

public static class Stringcipher 
    { 
     // This constant is used to determine the keysize of the encryption algorithm in bits. 
     // We divide this by 8 within the code below to get the equivalent number of bytes. 
     private const int Keysize = 256; 

     // This constant determines the number of iterations for the password bytes generation function. 
     private const int DerivationIterations = 1000; 

     public static string Encrypt(string plainText, string passPhrase) 
     { 
      // Salt and IV is randomly generated each time, but is preprended to encrypted cipher text 
      // so that the same Salt and IV values can be used when decrypting. 
      var saltStringBytes = Generate256BitsOfRandomEntropy(); 
      var ivStringBytes = Generate256BitsOfRandomEntropy(); 
      var plainTextBytes = Encoding.UTF8.GetBytes(plainText); 
      using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations)) 
      { 
       var keyBytes = password.GetBytes(Keysize/8); 
       using (var symmetricKey = new RijndaelManaged()) 
       { 
        symmetricKey.BlockSize = 256; 
        symmetricKey.Mode = CipherMode.CBC; 
        symmetricKey.Padding = PaddingMode.PKCS7; 
        using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, ivStringBytes)) 
        { 
         using (var memoryStream = new MemoryStream()) 
         { 
          using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) 
          { 
           cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); 
           cryptoStream.FlushFinalBlock(); 
           // Create the final bytes as a concatenation of the random salt bytes, the random iv bytes and the cipher bytes. 
           var cipherTextBytes = saltStringBytes; 
           cipherTextBytes = cipherTextBytes.Concat(ivStringBytes).ToArray(); 
           cipherTextBytes = cipherTextBytes.Concat(memoryStream.ToArray()).ToArray(); 
           memoryStream.Close(); 
           cryptoStream.Close(); 
           return Convert.ToBase64String(cipherTextBytes); 
          } 
         } 
        } 
       } 
      } 
     } 

     public static string Decrypt(string cipherText, string passPhrase) 
     { 
      // Get the complete stream of bytes that represent: 
      // [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText] 
      var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText); 
      // Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes. 
      var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize/8).ToArray(); 
      // Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes. 
      var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize/8).Take(Keysize/8).ToArray(); 
      // Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string. 
      var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize/8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize/8) * 2)).ToArray(); 

      using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations)) 
      { 
       var keyBytes = password.GetBytes(Keysize/8); 
       using (var symmetricKey = new RijndaelManaged()) 
       { 
        symmetricKey.BlockSize = 256; 
        symmetricKey.Mode = CipherMode.CBC; 
        symmetricKey.Padding = PaddingMode.PKCS7; 
        using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes)) 
        { 
         using (var memoryStream = new MemoryStream(cipherTextBytes)) 
         { 
          using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)) 
          { 
           var plainTextBytes = new byte[cipherTextBytes.Length]; 
           var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length); 
           memoryStream.Close(); 
           cryptoStream.Close(); 
           return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount); 
          } 
         } 
        } 
       } 
      } 
     } 

     private static byte[] Generate256BitsOfRandomEntropy() 
     { 
      var randomBytes = new byte[32]; // 32 Bytes will give us 256 bits. 
      using (var rngCsp = new RNGCryptoServiceProvider()) 
      { 
       // Fill the array with cryptographically secure random bytes. 
       rngCsp.GetBytes(randomBytes); 
      } 
      return randomBytes; 
     } 
    } 
+0

どうすればpassPhraseを作成できますか?私はENCRYPTION_KEY、塩とivから生成する必要がありますね。私は正しい? – David

+0

あなたのアプリケーション/コードだけがそれを解読するように、どこにユニークな文字列を作成するかは関係ありません。 。 。 –

+0

しかし、私は文字列を解読したい。それを暗号化しないでください。実際にアンドロイドクライアントによって既に暗号化された文字列と私はそれを解読する必要があります! – David

関連する問題