C#AES加密的Java等价物
我在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
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;i a=(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));
}
}