Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#AES加密的Java等价物_Java_Encryption_Encoding_Aes - Fatal编程技术网

C#AES加密的Java等价物

C#AES加密的Java等价物,java,encryption,encoding,aes,Java,Encryption,Encoding,Aes,我在C#中有以下代码。它使用AES对称算法对字节数组进行编码。我需要编写这个代码的Java等价物 class Program { static void Main(string[] args) { string a = "ABCDEFGHIJKLMNOP"; byte[] bytes = Encoding.ASCII.GetBytes(a); byte[] cipher = encode(bytes, "11111111222222

我在C#中有以下代码。它使用AES对称算法对字节数组进行编码。我需要编写这个代码的Java等价物

class Program
{
    static void Main(string[] args)
    {
        string a = "ABCDEFGHIJKLMNOP";
        byte[] bytes = Encoding.ASCII.GetBytes(a);
        byte[] cipher = encode(bytes, "1111111122222222111111112222222211111111222222221111111122222222", "66666666555555556666666655555555");
    }

    private static byte[] encode(byte[] toEncrypt, string sKey, string sIV)
    {
        byte[] IV = new byte[16];
        byte[] key = new byte[32];
        byte[] array = new byte[toEncrypt.Length];
        string s;

        for (int i = 0; i < IV.Length; ++i)
        {
            s = sIV.Substring(i * 2, 2);
            IV[i] = Convert.ToByte(s, 16);
        }

        for (int i = 0; i < key.Length; ++i)
        {
            s = sKey.Substring(i * 2, 2);
            key[i] = Convert.ToByte(s, 16);
        }

        MemoryStream filecrypt = new MemoryStream(array);

        AesManaged encrypt = new AesManaged();
        encrypt.Mode = CipherMode.CBC;
        encrypt.Padding = PaddingMode.None;
        encrypt.BlockSize = 128;
        encrypt.KeySize = 256;

        CryptoStream cs = new CryptoStream(filecrypt, encrypt.CreateEncryptor(key, IV), CryptoStreamMode.Write);
        cs.Write(toEncrypt, 0, toEncrypt.Length);
        cs.Close();

        return array;
    }
}
类程序
{
静态void Main(字符串[]参数)
{
字符串a=“ABCDEFGHIJKLMNOP”;
byte[]bytes=Encoding.ASCII.GetBytes(a);
byte[]cipher=编码(字节,“11111111 2222222 11111111111 2222222 11111111 22222222 11111 22222222”,“66666666 5555555555 666666 55555555”);
}
专用静态字节[]编码(字节[]到加密,字符串sKey,字符串sIV)
{
字节[]IV=新字节[16];
字节[]键=新字节[32];
byte[]数组=新字节[toEncrypt.Length];
字符串s;
对于(int i=0;i
这是我用Java编写的尝试。代码看起来不错,但输出不同,一定是出了问题

public class Main {

    public static void main(String [] args) {
        byte [] code = encode("ABCDEFGHIJKLMNOP".getBytes(), "1111111122222222111111112222222211111111222222221111111122222222", "66666666555555556666666655555555");
    }

    private static byte[] toByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        int a;
        int b;
        for (int i = 0; i < len; i += 2) {
            a = (Character.digit(s.charAt(i), 16) << 4);
            b = Character.digit(s.charAt(i+1), 16);
            int n = (Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i+1), 16);
                data[i / 2] = (byte) (n);
        }
        return data;
    }

    private static byte[] encode(byte[] toEncrypt, String skey, String siv)
    {
        byte[] key = toByteArray(skey);
        byte[] iv = toByteArray(siv);

        byte[] array = new byte[toEncrypt.length];

        Cipher cipher;

        try {
            cipher = Cipher.getInstance("AES/CBC/NoPadding");
            cipher.init(Cipher.ENCRYPT_MODE,  new SecretKeySpec(key, "AES"), new IvParameterSpec(iv));
            array = cipher.doFinal(array);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return array;
    }
}
公共类主{
公共静态void main(字符串[]args){
byte[]code=encode(“ABCDEFGHIJKLMNOP”.getBytes(),“11111111 22222222 11111111 22222222 11111 22222222”,“66666666 55555555 666666 555555”);
}
专用静态字节[]toByteArray(字符串s){
int len=s.length();
字节[]数据=新字节[len/2];
INTA;
int b;
对于(int i=0;ia=(Character.digit(s.charAt(i),16)就个人而言,如果您的目标是简单地用Java实现AES加密,那么您的代码不应该基于C#类。当然,它们可能类似,但Java已经有了强大的库

除此之外,我希望我的加密书能在这里向您解释,但不幸的是,我现在能做的最好的事情就是为您提供一个其他人尝试过的好例子:

  • (AES问题的具体答案)
  • (有多个好答案的向上投票的问题)
  • (JavaAES教程)
  • (Java AES 256加密/解密教程)
我希望这些链接能帮助你实现你的目标

另外,关于您的特定c#代码,我看不出您在Java中指定以下代码的位置:

encrypt.BlockSize = 128;
encrypt.KeySize = 256;
在第二个教程中,我建议您使用一个示例,其中他们指定密钥大小。我希望我能提供帮助!

我对C#不太了解,但通常您希望多个连续的加密结果不同。这就是为什么您为AES算法指定初始IV。加密代码可能如下所示:

  public String encrypt( String stringToEncrypt, IvParameterSpec ivSpec ) {
    if ( stringToEncrypt == null ) {
      return null;
    }
    try {
      Cipher cipher = Cipher.getInstance( "AES/CBC/PKCS5Padding");
      SecretKeySpec keySpec = new SecretKeySpec( key, "AES" );
      cipher.init( Cipher.ENCRYPT_MODE, keySpec, ivSpec );
      byte[] data = cipher.doFinal( stringToEncrypt.getBytes( "UTF-8" ) );
      return String.format( "%s:%s", Base64.encode( ivSpec.getIV() ), Base64.encode( data ) );
    } catch ( Exception e ) {
      throw new RuntimeException( "Unable to encrypt the string", e );
    }
  }
您的密钥和IV应该使用SecureRandom生成,因为它提供了java中最好的熵:

byte[] iv = new byte[32];
random.nextBytes( iv );
byte[] key = new byte[32];
random.nextBytes( key );
此外,您可能希望事后计算HMAC—java在这里也支持多种解决方案。通过检查接收方的HMAC,您可以防止填充oracle攻击

为了比较不同的加密结果,我会将它们进行比较


注意:将IV保存在密文旁边是可以的,它只是为了防止计算前的攻击。

您正在初始化
byte[]array=new byte[toEncrypt.length];
出于某种原因,但在加密之前您从未将
toEncrypt
的内容写入其中。您可以使用
System.arraycopy(toEncrypt,0,array,0,array.length);
,但它更易于使用

byte[] array;
...
array = cipher.doFinal(toEncrypt);
...
return array;
此代码应通过添加所需填充(默认为128位)来解密加密消息,但您需要提供加密密钥。 然而,这是我的C#版本的相同代码

 void DecryptMessage(string message)
    {
        var deserializedMessage = JsonConvert.DeserializeObject<List<string>>(message.ToString());
        byte[] decodedEncryptionKey = Convert.FromBase64String(encryptkey);
        byte[] data = Convert.FromBase64String(deserializedMessage[0]);
        byte[] iv = new byte[16];
        AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
        aes.BlockSize = 128;
        aes.KeySize = 128;
        aes.Mode = CipherMode.ECB;
        aes.Padding = PaddingMode.PKCS7;

        using (ICryptoTransform decrypt = aes.CreateDecryptor(decodedEncryptionKey, iv))
        {
            byte[] dest = decrypt.TransformFinalBlock(data, 0, data.Length);
            decrypt.Dispose();
            Console.WriteLine(Encoding.UTF8.GetString(dest));
        }
    }
void解密消息(字符串消息)
{
var deserializedMessage=JsonConvert.DeserializeObject(message.ToString());
字节[]decodedEncryptionKey=Convert.FromBase64String(encryptkey);
字节[]数据=Convert.FromBase64String(反序列化消息[0]);
字节[]iv=新字节[16];
AESCryptServiceProvider aes=新的AESCryptServiceProvider();
aes.BlockSize=128;
aes.KeySize=128;
aes.Mode=CipherMode.ECB;
aes.Padding=PaddingMode.PKCS7;
使用(ICryptoTransform decrypt=aes.CreateDecryptor(decodedEncryptionKey,iv))
{
字节[]dest=decrypt.TransformFinalBlock(数据,0,数据.Length);
decrypt.Dispose();
WriteLine(Encoding.UTF8.GetString(dest));
}
}

您如何看待每种情况下的输出?在调试器中(我要记住Java中的字节是有符号的)。如果你能用每种语言提供一个简短但完整的程序,我们就可以自己看到它了,这将更容易帮助你。在每种情况下都包括输入和输出。我还强烈建议你使用比
b
a
更具描述性的名称来表示键和IV…请不要更改你的问题在收到答案后不久。我将您的问题还原为早期版本。您所做的编辑引入了OFB,原因可能会使所有给定的答案过时。如果OFB有问题,您应该问一个新问题。我需要将我的代码基于C#,Java代码必须完全相同。我不需要指定BlockSize和KJava中的eySize(这些是默认值)。愚蠢的错误。就是这样,谢谢。我自己看不到。提问者可能没有给你应得的荣誉
 void DecryptMessage(string message)
    {
        var deserializedMessage = JsonConvert.DeserializeObject<List<string>>(message.ToString());
        byte[] decodedEncryptionKey = Convert.FromBase64String(encryptkey);
        byte[] data = Convert.FromBase64String(deserializedMessage[0]);
        byte[] iv = new byte[16];
        AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
        aes.BlockSize = 128;
        aes.KeySize = 128;
        aes.Mode = CipherMode.ECB;
        aes.Padding = PaddingMode.PKCS7;

        using (ICryptoTransform decrypt = aes.CreateDecryptor(decodedEncryptionKey, iv))
        {
            byte[] dest = decrypt.TransformFinalBlock(data, 0, data.Length);
            decrypt.Dispose();
            Console.WriteLine(Encoding.UTF8.GetString(dest));
        }
    }