【问题标题】:AES encryption for .NET, Java (android) and iOS.NET、Java (android) 和 iOS 的 AES 加密
【发布时间】:2011-11-22 00:05:34
【问题描述】:

使用这篇文章 Encryption compatible between Android and C# 中的示例,我已经成功地在为我的 Android 应用程序提供 XML 提要的 .NET 应用程序之间实现了 AES 加密。

现在,我正在尝试对该应用的 iOS 版本使用相同的实现。我找到了一些非常好的适用于 iOS 的 AES 示例,但到目前为止,似乎没有一个与我目前使用的方案相匹配。据我所知,问题在于 C# 和 Java 之间共享的 16 字节密钥(rawSecretKey)。在 iOS 示例中,我无法找到使用相同字节数组设置的类似键。它有密码,但没有字节数组。

如果有人知道一个很好的例子来说明这种类型的实现,那将非常有帮助。我发现的一个 iOS 示例是 http://dotmac.rationalmind.net/2009/02/aes-interoperability-between-net-and-iphone/,但同样,我看不到如何包含我帖子顶部第一个链接中引用的 16 字节数组。

【问题讨论】:

  • 如果 iOS 是从密码中派生密钥,那么是否可以在 Android 中复制相同的密钥派生函数?
  • 密码短语在不同平台之间是一个常数——那个特定的密钥不是问题。使用的 16 字节数组更是如此——我发现的 iOS 示例不包含该值(或者至少我不够聪明,无法看到它)。我也无法更改 Android 实现,因为它正在生产中,我们的用户已经使用现有方法加密了数据。我只需要为 iOS 复制它。
  • 顺便说一句 - 字节密钥也是一个常数,它不是从任何东西派生的。我刚刚创建了密钥,它看起来像: private static byte[] rawSecretKey = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
  • 你需要查看iOS文档,看看是否有办法传入字节密钥,而不是密码。否则,您需要确定生成现有 Android 密钥的密码短语并在 iOS 中使用该密码短语。我不是 iOS 专家,所以在这方面我帮不上什么忙。
  • rossum...感谢 cmets,但不太确定它们是我需要的。我控制密码短语和 16 字节密钥的值,我需要在加密/解密例程中使用它们。我可以轻松地在 iOS 中设置密码——我只需要告诉 iOS 16 字节密钥是什么,就像我在 Java 和 .NET 实现中所做的那样。查看我的问题中的第一个链接,您会看到我用作 Java 和 .NET 基础的代码。

标签: java android ios encryption aes


【解决方案1】:

.Net 和 IOS 都支持 PKCS7Padding,但 Java 不支持(除非使用一些第三方库)

.Net 和 Java 都支持 ISO10126Padding,但 IOS 不支持(除非使用一些第三方库)

所以我认为您需要为 IOS 和 Java 提供单独的 .net 加密代码。

以下是一些代码示例:

IOS:

+ (NSData*)encryptData:(NSData*)data :(NSData*)key :(NSData*)iv
{    
    size_t bufferSize = [data length]*2;
    void *buffer = malloc(bufferSize);
    size_t encryptedSize = 0;    
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,                                          
                                          [key bytes], [key length], [iv bytes], [data bytes], [data length],                                          
                                          buffer, bufferSize, &encryptedSize);  
    if (cryptStatus == kCCSuccess)      
        return [NSData dataWithBytesNoCopy:buffer length:encryptedSize];    
    else
        free(buffer);
    return NULL;
}

对于 .NET:

public static byte[] AesEncrypt(byte[] bytes, byte[] key, byte[] iv)
{
    if (bytes == null || bytes.Length == 0 || key == null || key.Length == 0 || iv == null || iv.Length == 0)
        throw new ArgumentNullException();

    using (var memoryStream = new MemoryStream())
    {
        using (var rijndaelManaged = new RijndaelManaged { Key = key, IV = iv, Padding = PaddingMode.PKCS7, Mode = CipherMode.CBC })
        {
            using (var cryptoStream = new CryptoStream(memoryStream, rijndaelManaged.CreateEncryptor(key, iv), CryptoStreamMode.Write))
            {
                cryptoStream.Write(bytes, 0, bytes.Length);
            }
        }
        return memoryStream.ToArray();
    }
}

对于 Java:

public static byte[] encrypt(byte[] bytes, byte[] key, byte[] iv)
        throws Exception
{
    Cipher cipher = Cipher.getInstance("AES/CBC/ISO10126Padding");
    cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"),
            new IvParameterSpec(iv));
    return cipher.doFinal(bytes);
}

我只提供加密的代码,因为解密代码非常相似,你可以很容易地弄清楚。

还有什么问题请留下cmets。

【讨论】:

  • "PKCS5Padding" 在 Java 中与 PKCS#7 填充相同。在标准中,填充算法仅在块大小上有所不同(PKCS#5 为 8 字节,PKCS#7 为 16 字节),但在大多数实现中,它们与块大小和 Java(或更准确地说,Oracle 和充气城堡供应商)他们当然是。
  • @owlstead,正如您所说,“在大多数实现中”。如果块大小不是 8 字节,则它们是不相同的。我会尝试一下:Java 中的 PKCS5 和 C# 中的 PKCS7,看看它们是否可以相互通信。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-28
  • 1970-01-01
  • 2013-10-12
  • 1970-01-01
  • 2017-05-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多