需要Java等效的C#加密代码

时间:2015-04-21 18:04:36

标签: java c# encryption

我有以下c#代码,但在Java中需要完全相同的算法。无论c#代码质量如何,我都无能为力。我只关心Java编码的字符串是否相同。

    //Run GetToken to get encrypted string
    var token = GetToken(AMessage, account_name, api_key);

    private static byte[] GetBytes(string value, byte[] salt, int length)
    {
        var deriveBytes = new Rfc2898DeriveBytes(value, salt);
        return deriveBytes.GetBytes(length);
    }

    private static string GetToken(string session, string accountName, string apiKey)
    {
        byte[] encrypted;

        using (AesManaged aes = new AesManaged())
        {
            var salt = Encoding.Default.GetBytes(apiKey);
            var key = GetBytes(accountName, salt, aes.KeySize / 8);
            var vector = GetBytes(accountName, salt, aes.BlockSize / 8);

            aes.Key = key;
            aes.IV = vector;

            var memoryStream = new MemoryStream();
            using (var encryptor = aes.CreateEncryptor(aes.Key, aes.IV))
            {
                using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                {
                    using (var writer = new StreamWriter(cryptoStream))
                    {
                        writer.Write(session);
                    }
                }
            }
            encrypted = memoryStream.ToArray();
        }

        return Convert.ToBase64String(encrypted);
    }

1 个答案:

答案 0 :(得分:0)

我能够在朋友的帮助下拼凑出答案。我认为发布答案会很有帮助,所以人们看起来找到的不仅仅是未解答的问题。我知道有很多加密问题,可能不建议使用上面的c#加密方法。希望这个c#到java转换可以帮助某人。以下是上述c#代码问题的java代码答案。

享受。

private static String Encrypt(String DecryptedText, String accountName, String apiKey) {
    byte[] EncryptedStr = {};

    if (accountName.length() < 5 || apiKey.length() < 5) {
        System.out.println("Name too short");
        return DatatypeConverter.printBase64Binary(EncryptedStr);
    }
    try {
        byte[] salt = apiKey.getBytes();
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");

        KeySpec KeySpec = new PBEKeySpec(accountName.toCharArray(), salt, 1000, 256);
        SecretKey key = factory.generateSecret(KeySpec);

        KeySpec VectorSpec = new PBEKeySpec(accountName.toCharArray(), salt, 1000, 128);
        SecretKey vector = (SecretKey) factory.generateSecret(VectorSpec);

        SecretKey secretKey = new SecretKeySpec(key.getEncoded(), "AES");

        byte[] ivKeyBytes = vector.getEncoded();
        byte[] iv = new byte[16]; // Get IV bytes from the
        for (int i = 0; i < iv.length; ++i)
                iv[i] = ivKeyBytes[i];
        IvParameterSpec ivParm = new IvParameterSpec(iv);

        Log("Salt:", false);
        Log(salt, true);
        Log("Key:", false);
        Log(secretKey.getEncoded(), true);
        Log("Vector:", false);
        Log(iv, true);

        // IN C# they are using KeySize=256, Mode=CBC, Padding=PKCS7,
        // PKCS7 padding doesn't exist in java so use PKCS5 and hope it works correctly.
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

        // NOTE: Added ivParam to initialize the IV parameter, w/o the first block is off.
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParm);
        EncryptedStr = cipher.doFinal(DecryptedText.getBytes("UTF-8"));
    } catch (Exception e) {
        System.out.println("Exc:" + e.getMessage());
        e.printStackTrace(System.out);
    }

    return DatatypeConverter.printBase64Binary(EncryptedStr);
}

}