Java中用于C#构造的加密解密等价物

Java中用于C#构造的加密解密等价物,第1张

概述我有一个使用Rijndael的加密mp4,我用以下方式在C#中解密.System.Security.Cryptography.Rijndaelcrypt=System.Security.Cryptography.Rijndael.Create();crypt.Key=convertedSecureString;byte[]initializationVectorLength=newbyte[sizeof(int)];CryptoStreamcr

我有一个使用Rijndael的加密mp4,我用以下方式在C#中解密.

System.Security.Cryptography.Rijndael crypt = System.Security.Cryptography.Rijndael.Create();crypt.Key = convertedsecurestring;byte[] initializationVectorLength = new byte[sizeof(int)];CryptoStream cryptostream = new CryptoStream(inputStream, crypt.CreateDecryptor(), CryptoStreamMode.Read);byte[] buffer = new byte[1024];int len;while ((len = cryptostream.Read(buffer, 0, buffer.Length)) > 0){    outputStream.Write(buffer, 0, len);    buffer = new byte[1024];}outputStream.Flush();cryptostream.Close();inputStream.Close();

现在我需要将此代码转换为Java / AndroID等效代码.我不确定从哪里开始坦率地说.我对很多选项感到困惑 – 有人说使用Bouncy Castle,有些人说Apache Commons,有些人说是原生的Java lib.我该怎么做呢.我该怎么办CryptoStream等?

UPDATE

我在C#中使用以下代码来分配密钥

byte[] convertedsecurestring = new byte[this.key.Length];IntPtr ptr = System.Runtime.InteropServices.Marshal.securestringToBSTR(this.key);for (int i = 0, j = 0; i < this.key.Length * UnicodeByteLength; i = i + UnicodeByteLength, j++){    convertedsecurestring[j] = System.Runtime.InteropServices.Marshal.ReadByte(ptr, i);}try{    crypt.Key = convertedsecurestring;}

钥匙是安全的.我在Java中拥有等效的不安全密钥.我如何将这段代码转换为Java

UPDATE

  Rfc2898DeriveBytes newKey = new Rfc2898DeriveBytes(crypt.Key.ToString(), crypt.IV);                Array.copy(newKey.GetBytes((int)crypt.KeySize / 8), crypt.Key, (int)crypt.KeySize / 8);                Array.copy(newKey.GetBytes((int)crypt.BlockSize / 8), crypt.IV, (int)crypt.BlockSize / 8);

我在C#中使用它来使用Rfc 2898来修改密钥并导出字节 – 我无法在Java中找到等价物 – 我在第二条评论中找到了Java equivalent of C#’s Rfc2898DerivedBytes – 但是我为iterator和dklen提供了什么值?

解决方法:

你需要获得Cipher对象.这是获取它的一种方法,使用byte [] aesKey和byte [] iv(初始化向量,AES必须始终为16个字节).

// aesKey is 128, 196 or 256-bit key (8, 12 or 16 byte array)SecretKeySpec key = new SecretKeySpec(aesKey, "AES");// initialization vectorIvParameterSpec ivSpec = new IvParameterSpec(iv);// create and initialize cipher objectCipher cipher = Cipher.getInstance("AES/CBC/PKCS5padding");cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);

一旦你有Cipher对象处于解密模式,你可以使用update方法用加密数据提供它,它将返回纯文本数据.完成后,必须调用其中一个doFinal方法才能获得最终块.

或者,您可以使用Cipher对象创建CipherInputStream,并使用提供加密数据的原始输入流.您从CipherinputStream读取数据,然后CipherinputStream从原始输入流中读取数据,对其进行解密,并返回纯文本数据.

对于加密,您需要将Cipher.ENCRYPT_MODE传递给Cipher.init方法,并使用CipherOutputStream代替.

更新:完整示例,或多或少等同于原始C#代码:

// Algorithm, mode and padding must match encryption.// Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5padding");// If you have Bouncycastle library installed, you can use// Rijndael/CBC/PKCS7padding directly.Cipher cipher = Cipher.getInstance("Rijndael/CBC/PKCS7padding");// convertedsecurestring and initVector must be byte[] with correct lengthcipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(convertedsecurestring, "AES"),    new IvParameterSpec(initVector));CipherinputStream cryptoStream = new CipherinputStream(inputStream, cipher);byte[] buffer = new byte[1024];int len = cryptoStream.read(buffer, 0, buffer.length);while (len > 0) {    outputStream.write(buffer, 0, len);    len = cryptoStream.read(buffer, 0, buffer.length);}outputStream.flush();cryptoStream.close();// no need to close inputStream here, as cryptoStream will close it

默认情况下,Java不支持Rijndael算法(AES可能或可能不起作用,请参阅其他答案)和PKCS7填充.你需要为此安装Bouncycastle扩展,然后只使用Cipher.getInstance(“Rijndael / CBC / PKCS7padding”);.为什么CBC和PKCS7填充?这些似乎是System.Security.Cryptography.Rijndael课程的默认值.如果我弄错了,请根据您的情况使用正确的模式和填充.

总结

以上是内存溢出为你收集整理的Java中用于C#构造的加密/解密等价物全部内容,希望文章能够帮你解决Java中用于C#构造的加密/解密等价物所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1112860.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-29
下一篇2022-05-29

发表评论

登录后才能评论

评论列表(0条)

    保存