使用C和Java进行RC4加密/解密

使用C和Java进行RC4加密/解密,java,c#,encryption,rc4-cipher,Java,C#,Encryption,Rc4 Cipher,我甚至使用AES算法来加密和解密文件,但根据我的研究,该算法的性能比Java中的RC4算法慢。 我正在使用此代码对C中的文件进行加密 public static class RC4 { public static byte[] Encrypt(byte[] key, byte[] data) { return EncryptOutput(key, data).ToArray(); } private static byte[] EncryptIn

我甚至使用AES算法来加密和解密文件,但根据我的研究,该算法的性能比Java中的RC4算法慢。 我正在使用此代码对C中的文件进行加密

public static class RC4
{
    public static byte[] Encrypt(byte[] key, byte[] data)
    {
        return EncryptOutput(key, data).ToArray();
    }

    private static byte[] EncryptInitalize(byte[] key)
    {
        byte[] s = Enumerable.Range(0, 256)
          .Select(i => (byte)i)
          .ToArray();

        for (int i = 0, j = 0; i < 256; i++)
        {
            j = (j + key[i % key.Length] + s[i]) & 255;

            Swap(s, i, j);
        }

        return s;
    }

    private static IEnumerable<byte> EncryptOutput(byte[] key, IEnumerable<byte> data)
    {
        byte[] s = EncryptInitalize(key);

        int i = 0;
        int j = 0;

        return data.Select((b) =>
        {
            i = (i + 1) & 255;
            j = (j + s[i]) & 255;

            Swap(s, i, j);

            return (byte)(b ^ s[(s[i] + s[j]) & 255]);
        });
    }

    private static void Swap(byte[] s, int i, int j)
    {
        byte c = s[i];

        s[i] = s[j];
        s[j] = c;
    }
}

我需要用C加密一个文件并用java解密该文件,但没有发现两种语言的实现。

根据您的评论,我假设您想知道如何加快加密/解密过程,并且更改主算法不是强制性的

您可以查看AES的不同模式。例如,计数器CTR模式下的AES明显快于经常使用的密码块链接CBC

试着创建你喜欢的密码

Cipher myCipher = Cipher.getInstance("AES/CTR/NoPadding");
您应该会看到性能的提高。此外,使用NoPadding将保持大小与纯文本相同

是的,我知道CTR模式将AES转换为流密码,更不用说我的评论了

更新

我过去曾按照以下思路使用过:

    Key key = new SecretKeySpec(yourKeyValue, "AES");
    Cipher enc = Cipher.getInstance("AES/CTR/NoPadding");
    enc.init(Cipher.ENCRYPT_MODE, key);
    // Get the IV that was generated
    byte[] iv = enc.getIV();
    // Encrypt your data
    ...
    Cipher dec = Cipher.getInstance("AES/CTR/NoPadding");
    dec.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
    // Decrypt your data
    ...

通过实现的此解决方案在使用AES解密文件时显示了更好的性能。加密和解密文件,我只实现了字符串到字节数组的转换

Java代码

C代码


问题到底是什么?您想要一个在java和C中都适用于RC4的加密/解密实现吗?不要仅仅因为您有轶事证据表明它可能会慢一些而选择RC4而不是AES。RC4上有一个安全漏洞,加密敏感数据不是一种安全的方法。您是否对AES进行了基准测试?它的加密速度可能比您从磁盘读取数据的速度还要快。RC4是一种流密码,已知它很弱。您应该问问自己是否真的需要流密码。AES是一种分组密码,其256bit变体相当强大。在Android应用程序中,AES算法解密视频文件需要27秒。AES确实是一个更安全的部署,但是我需要使它更灵活。关于如何解决这个问题有什么建议吗?需要使用CTR来初始化向量吗?dcipher.initCipher.DECRYPT_模式,密钥,paramSpec@RenanPrológica虽然您会通过一个IV,但在CTR模式下它实际上被称为nonce,并且对于使用相同密钥的每个加密,它必须是唯一的。是的,您需要在加密时从密码初始化保存IV。我将用一个例子来更新。实际上使用CTR模式更快,但我有一个Windows窗体中的应用程序来加密文件,并且没有实现C CTR模式。很遗憾,我不是很精通C。在安全性和速度之间总是有一个权衡,这是你自己要做的。你可以看看这里,帮助你做出决定。
 package org.ferris.aes.crypto;

import java.io.UnsupportedEncodingException;
import java.security.Key;
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;

/**
 *
 * @author Michael Remijan mjremijan@yahoo.com @mjremijan
 */
public class AesBase64Wrapper {

    private static String IV = "IV_VALUE_16_BYTE"; 
    private static String PASSWORD = "PASSWORD_VALUE"; 
    private static String SALT = "SALT_VALUE"; 

    public String encryptAndEncode(String raw) {
        try {
            Cipher c = getCipher(Cipher.ENCRYPT_MODE);
            byte[] encryptedVal = c.doFinal(getBytes(raw));
            String s = getString(Base64.encodeBase64(encryptedVal));
            return s;
        } catch (Throwable t) {
            throw new RuntimeException(t);
        }
    }

    public String decodeAndDecrypt(String encrypted) throws Exception {
        byte[] decodedValue = Base64.decodeBase64(getBytes(encrypted));
        Cipher c = getCipher(Cipher.DECRYPT_MODE);
        byte[] decValue = c.doFinal(decodedValue);
        return new String(decValue);
    }

    private String getString(byte[] bytes) throws UnsupportedEncodingException {
        return new String(bytes, "UTF-8");
    }

    private byte[] getBytes(String str) throws UnsupportedEncodingException {
        return str.getBytes("UTF-8");
    }

    private Cipher getCipher(int mode) throws Exception {
        Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
        byte[] iv = getBytes(IV);
        c.init(mode, generateKey(), new IvParameterSpec(iv));
        return c;
    }

    private Key generateKey() throws Exception {
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        char[] password = PASSWORD.toCharArray();
        byte[] salt = getBytes(SALT);

        KeySpec spec = new PBEKeySpec(password, salt, 65536, 128);
        SecretKey tmp = factory.generateSecret(spec);
        byte[] encoded = tmp.getEncoded();
        return new SecretKeySpec(encoded, "AES");
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;

namespace EncryptDecryptTest
{
    class Program
    {
        class AesBase64Wrapper
        {
            private static string IV = "IV_VALUE_16_BYTE";
            private static string PASSWORD = "PASSWORD_VALUE";
            private static string SALT = "SALT_VALUE";

            public static string EncryptAndEncode(string raw)
            {
                using (var csp = new AesCryptoServiceProvider())
                {
                    ICryptoTransform e = GetCryptoTransform(csp, true);
                    byte[] inputBuffer = Encoding.UTF8.GetBytes(raw);
                    byte[] output = e.TransformFinalBlock(inputBuffer, 0, inputBuffer.Length);
                    string encrypted = Convert.ToBase64String(output);
                    return encrypted;
                }
            }

            public static string DecodeAndDecrypt(string encrypted)
            {
                using (var csp = new AesCryptoServiceProvider())
                {
                    var d = GetCryptoTransform(csp, false);
                    byte[] output = Convert.FromBase64String(encrypted);
                    byte[] decryptedOutput = d.TransformFinalBlock(output, 0, output.Length);
                    string decypted = Encoding.UTF8.GetString(decryptedOutput);
                    return decypted;
                }
            }

            private static ICryptoTransform GetCryptoTransform(AesCryptoServiceProvider csp, bool encrypting)
            {
                csp.Mode = CipherMode.CBC;
                csp.Padding = PaddingMode.PKCS7;
                var spec = new Rfc2898DeriveBytes(Encoding.UTF8.GetBytes(PASSWORD), Encoding.UTF8.GetBytes(SALT), 65536);
                byte[] key = spec.GetBytes(16);


                csp.IV = Encoding.UTF8.GetBytes(IV);
                csp.Key = key;
                if (encrypting)
                {
                    return csp.CreateEncryptor();
                }
                return csp.CreateDecryptor();
            }
        }

        static void Main(string[] args)
        {
            string encryptMe;
            string encrypted;
            string decrypted;

            encryptMe = "please encrypt me";
            Console.WriteLine("encryptMe = " + encryptMe);

            encrypted = AesBase64Wrapper.EncryptAndEncode(encryptMe);
            Console.WriteLine("encypted: " + encrypted);

            decrypted = AesBase64Wrapper.DecodeAndDecrypt(encrypted);
            Console.WriteLine("decrypted: " + decrypted);

            Console.WriteLine("press any key to exit....");
            Console.ReadKey();
        }
    }
}