繁体   English   中英

iPhone(Objective-c)和Java之间的AES差异

[英]AES difference between iPhone (Objective-c) and Java

我整天都在试着解决这个问题......

我有一个在iPhone上运行的objective-c客户端,连接到Java服务器。 iPhone正在使用AES加密数据,但我无法在服务器上解密它。 我正在使用已知的密码短语和消息(单个字符串)并在iPhone上生成字节数组,使用相同的密钥和消息在Java服务器上生成比较字节数组但字节数组完全不同(因此不能在Java端解码)。

客户端正在使用具有以下设置的CommonCrypto库...

数据是一个NSData保持使用单词“消息” dataUsingEncoding:NSASCIIStringEncoding密钥是NSData保持短语“1234567891123456”再次使用上述的编码。 算法是kCCAlgorithmAES128选项是kCCOptionsPKCS7Padding (我认为它等同于服务器上的ECB?!)

服务器正在使用以下代码...

byte[] key = "1234567891123456".getBytes();
Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding");

SecretKeySpec k =  new SecretKeySpec(key, "AES");
c.init(Cipher.ENCRYPT_MODE, k);
byte[] encryptedData = c.doFinal("message".getBytes());

但是encryptedData中的数据与在objective-c代码中生成的数据不匹配,字节数组完全不同。

任何人都可以看到任何明显我做错了吗? 认为设置都是一样的...... :(

  • 更新 - 根据要求....

好的,所以这里......

iPhone客户端正在加密以下字符串“消息”它使用密钥“1234567891123456”它使用初始化矢量“1010101010101010”它使用AES128,具有CBC模式(据我所知)和kCCOptionsPKCS7Padding的选项。

加密结果(使用base64编码)是UHIYllDFAXl81ZM7OZPAuA ==

服务器正在使用相同的密钥和初始化向量加密相同的字符串。 它使用以下Cipher.getInstance(“AES / CBC / PKCS5Padding”);

加密的结果(使用base64编码)是ALBnFIHysLbvAxjvtNo9vQ ==

谢谢。

  • 更新2 - 按要求......

这是iPhone代码....

NSData *toencrypt = [@"message" dataUsingEncoding:NSASCIIStringEncoding];

NSData *pass = [@"1234567891123456" dataUsingEncoding:NSASCIIStringEncoding];

NSData *iv = [@"1010101010101010" dataUsingEncoding:NSASCIIStringEncoding];    

CCCryptorStatus status = kCCSuccess;

NSData *encrypted = [toencrypt dataEncryptedUsingAlgorithm:kCCAlgorithmAES128 key:pass initializationVector:iv options:kCCOptionPKCS7Padding error:&status];

NSString *text = [NSString base64StringFromData:encrypted length:[encrypted length]];

用于加密的NSData类别来自这里......

http://github.com/AlanQuatermain/aqtoolkit/tree/master/CommonCrypto/

顺便说一下,我检查了toencrypt,pass和iv中的字节数组,它们与服务器上的字节数组相匹配。

这不是我的区域,但在客户端看起来像你有PKCS7但在服务器上你有PKCS5

我刚碰到了同样的问题。 我在iOS客户端上使用CommonCrypto,使用设置:

NSData * encrypted = [data dataEncryptedUsingAlgorithm:kCCAlgorithmAES128 key:pass initializationVector:iv options:kCCOptionPKCS7Padding error:&status];

服务器使用Cipher.getInstance("AES/CBC/PKCS5Padding"); 使用与客户端相同的密钥和初始化向量。

在最后几个小时撞到我的头后,我终于dataEncryptedUsingAlgorithm Jason的建议,检查了dataEncryptedUsingAlgorithm例程,并在FixKeyLengths之后打印出了keyData 事实证明我的128位密钥扩展到192位,最后添加了0。 修好后,一切正常。 :)

更新:我的答案大约在2年前发布,这个问题似乎在最新的NSData + CommonCrypto代码中得到修复。 具体来说,这是导致问题的部分:

static void FixKeyLengths( CCAlgorithm algorithm, NSMutableData * keyData, NSMutableData * ivData )
{
  NSUInteger keyLength = [keyData length];
  switch ( algorithm )
  {
    case kCCAlgorithmAES128:
    {
      if ( keyLength <= 16 )
      {
        [keyData setLength: 16];
      }
      else if ( keyLength <= 24 )
      {
        [keyData setLength: 24];
      }
      else
      {
        [keyData setLength: 32];
      }

      break;
    }

第一次检查keyLength <= 16之前没有。

如果你现在仍然遇到问题,那可能就是别的了。

iPhone使用AES的模式是什么? 你没有列出任何东西,所以也许这意味着它没有使用链接(ECB)。

但是,在Java端,您使用的是CBC,但未指定初始化向量。 这绝对是错误的。 如果您确实在使用CBC, 必须使用加密期间使用的IV。 IV不是秘密; 它可以与密文一起发送。

如果您确实在使用ECB,则没有IV,但您的Java指定了错误的模式。

根据您的样本,服务器正确执行,而客户端则没有。

看看这些数据,我猜猜关键是错的。 请告诉我们iPhone代码,特别是从“1234567891123456”到您的密钥的代码。

我最近在另一个项目中遇到了这个问题。 问题是密钥是一个字节太长,无法容纳dataEncryptedUsingAlgorithm方法内的char缓冲区。

问题是NSString上的getBytes方法是软故障的。 它会将大部分字符串复制到缓冲区中,但由于密钥是一个字节太长,它会通过将第一个字符设置为NUL (char 0)将操作“标记”为失败。

在Xcode中进入该方法,看看你的密钥char [16]缓冲区是什么样的。 它可能有同样的问题,并且内容为{ 0, '2', '3', '4', ... }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM