使用 Objective-C 加密数据并使用 Java 解密数据问题

2023-12-09

我有一个 iPhone 解决方案,它使用 XML 在客户端(移动设备)和服务器(Java)之间传输数据。由于传输的信息类型不同,消息 (XML) 的某些部分必须加密。我计划使用 AES 128 来加密和解密这两个端点之间的数据。

首先使用 Object-C 的 CommonCrypto 框架对敏感数据进行加密,然后在 Java 服务器 (Servlet) 内对数据进行解密。

我是安全协议和标准的新手,基本上我的代码是我可以在 Apple 开发论坛/资源和互联网(Google)上收集的信息组的子集:-)

基本流程是:

  1. 数据使用 AES 加密(使用预设密钥)。
  2. 加密的字节放入 XML 中(使用 base64)
  3. 数据从 XML 中收集,并使用相同的预设密钥进行解密;

Object-C代码的加密部分是:

char keyPtr [ kCCKeySizeAES128 +1 ];
bzero( keyPtr, sizeof(keyPtr) );

// The secret key is masked for obvious reason, but you can use "12345678912345678912345678912345"
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

NSUInteger dataLength = [data length];
// Initialization vector; dummy in this case 0's.
uint8_t iv[ kCCBlockSizeAES128 ];
memset((void *) iv, 0x0, (size_t) sizeof(iv));
/*
 For block ciphers, the output size will always be less than or
 equal to the input size plus the size of one block.
*/
size_t bufferSize = (dataLength + kCCBlockSizeAES128);
void  *buffer     = malloc(bufferSize);
memset(buffer, 0x0, bufferSize);

size_t numBytesEncrypted    = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, 
                                      kCCOptionECBMode + kCCOptionPKCS7Padding,
                                      keyPtr, kCCKeySizeAES128,
                                      iv, [data bytes], dataLength, /* input */
                                      buffer, bufferSize, /* output */
                                      &numBytesEncrypted);

if (cryptStatus == kCCSuccess) {
    return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}

free(buffer); //free the buffer;
return nil;

Java代码部分是:

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
byte[] keyBytes = DES_KEY.getBytes(); //<== The same as above

SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");

try {
    // Return the raw bytes 
    byte []data = Base64.decode(encryptedContent);

    // Gets the Cipher...
    final Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
    cipher.init(Cipher.DECRYPT_MODE, keySpec);

    String resultString = new String(cipher.doFinal(data));
} catch (Exception ex) {
    ...
}

在 Java 服务器中运行上述解决方案时出现的错误是:

15:57:43,671 ERROR [STDERR] com.iteatros.aim.services.ServiceException: javax.crypto.BadPaddingException: pad block corrupted
15:57:43,674 ERROR [STDERR]     at com.iteatros.aim.services.security.SecurityWrapper.decrypt3DESBase64StringData(SecurityWrapper.java:109)
15:57:43,674 ERROR [STDERR]     at com.iteatros.aim.services.db.LoginDAO.login(LoginDAO.java:53)
15:57:43,674 ERROR [STDERR]     at com.iteatros.aim.services.AbstractService.authenticate(AbstractService.java:278)
15:57:43,674 ERROR [STDERR]     at com.iteatros.aim.services.AbstractService.doPost(AbstractService.java:165)
15:57:43,674 ERROR [STDERR]     at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
15:57:43,674 ERROR [STDERR]     at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
15:57:43,674 ERROR [STDERR]     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
15:57:43,675 ERROR [STDERR]     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
15:57:43,675 ERROR [STDERR]     at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
15:57:43,675 ERROR [STDERR]     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
15:57:43,676 ERROR [STDERR]     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
15:57:43,676 ERROR [STDERR]     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)
15:57:43,676 ERROR [STDERR]     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
15:57:43,676 ERROR [STDERR]     at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:190)
15:57:43,676 ERROR [STDERR]     at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92)
15:57:43,676 ERROR [STDERR]     at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)
15:57:43,676 ERROR [STDERR]     at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)
15:57:43,677 ERROR [STDERR]     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
15:57:43,677 ERROR [STDERR]     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
15:57:43,677 ERROR [STDERR]     at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)
15:57:43,677 ERROR [STDERR]     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
15:57:43,677 ERROR [STDERR]     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)
15:57:43,677 ERROR [STDERR]     at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829)
15:57:43,677 ERROR [STDERR]     at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:601)
15:57:43,677 ERROR [STDERR]     at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
15:57:43,677 ERROR [STDERR]     at java.lang.Thread.run(Thread.java:680)

我知道不需要完整的堆栈,但无论如何......

提前谢谢。

Joao


这段代码对我有用。看一下:

AES 128 IOS

+ (NSString *) encrypt:(NSString *) dataToEncrypt withKey:(NSString*) key{    


NSData *data = [dataToEncrypt dataUsingEncoding:NSUTF8StringEncoding];
NSData *mData = [key dataUsingEncoding:NSUTF8StringEncoding];

CCCryptorStatus ccStatus = kCCSuccess;


// Begin to calculate bytesNeeded....

size_t bytesNeeded = 0;

ccStatus = CCCrypt(kCCEncrypt,
                   kCCAlgorithmAES,
                   kCCOptionECBMode | kCCOptionPKCS7Padding,
                   [mData bytes],
                   [mData length],
                   nil,
                   [data bytes],
                   [data length],
                   NULL,
                   0,
                   &bytesNeeded);

if(kCCBufferTooSmall != ccStatus){

    NSLog(@"Here it must return BUFFER TOO SMALL !!");
    return nil;
}

// .....End
// Now i do the real Crypting

char* cypherBytes = malloc(bytesNeeded);
size_t bufferLength = bytesNeeded;

if(NULL == cypherBytes)
    NSLog(@"cypherBytes NULL");

ccStatus = CCCrypt(kCCEncrypt,
                   kCCAlgorithmAES,
                   kCCOptionECBMode | kCCOptionPKCS7Padding,
                   [mData bytes],
                   [mData length],
                   nil,
                   [data bytes],
                   [data length],
                   cypherBytes,
                   bufferLength,
                   &bytesNeeded);

if(kCCSuccess != ccStatus){
    NSLog(@"kCCSuccess NO!");
    return nil;
}

return [Base64 encode:[NSData dataWithBytes:cypherBytes length:bufferLength]];
}

JAVA

public static void encrypt_AES(String message){

        Cipher ecipher;
        try {
            // generate secret key using DES algorithm
            SecretKeySpec key = new SecretKeySpec(theKey.getBytes("UTF-8"), "AES");

            ecipher = Cipher.getInstance("AES/ECB/PKCS7Padding");

            // initialize the ciphers with the given key
            ecipher.init(Cipher.ENCRYPT_MODE, key);

            byte[] encrypted = ecipher.doFinal(message.getBytes("UTF-8"));

        }catch (Exception e) {
            //    
            e.printStackTrace();
        }

    }

我在这里找到了 Base64 类:http://www.imthi.com/blog/programming/iphone-sdk-base64-encode-decode.php

希望它可以帮助别人

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Objective-C 加密数据并使用 Java 解密数据问题 的相关文章

  • PHP - hash_pbkdf2 函数

    我正在尝试使用此 php 函数执行一个函数来哈希密码 http be php net manual en function hash pbkdf2 php http be php net manual en function hash pb
  • org.hibernate.QueryException:无法解析属性:文件名

    我正在使用休眠Criteria从列中获取值filename在我的桌子上contaque recording log 但是当我得到结果时 它抛出异常 org hibernate QueryException 无法解析属性 文件名 com co
  • 如何将 Mat (opencv) 转换为 INDArray (DL4J)?

    我希望任何人都可以帮助我解决这个任务 我正在处理一些图像分类并尝试将 OpenCv 3 2 0 和 DL4J 结合起来 我知道DL4J也包含Opencv 但我认为它没什么用 谁能帮我 如何转换成 INDArray 我尝试阅读一些问题here
  • 如何在代理后面安装 Eclipse Neon

    对于 Neon Eclipse 附带了一个安装程序 我在安装程序中找不到任何配置菜单 我的java版本是 java version java version 1 8 0 72 Java TM SE Runtime Environment b
  • Kotlin 未解决的参考:CLI 上 gradle 的 println

    放一个printlnkotlin 函数返回之前的语句会崩溃 堆栈跟踪 thufir dur NetBeansProjects kotlin thufir dur NetBeansProjects kotlin gradle clean bu
  • 如何使用 Hibernate (EntityManager) 或 JPA 调用 Oracle 函数或过程

    我有一个返回 sys refcursor 的 Oracle 函数 当我使用 Hibernate 调用该函数时 出现以下异常 Hibernate call my function org hibernate exception Generic
  • 使用 Guice 优化注册表

    你好 今天思考了一种优化 有一些疑问 语境 我正在使用 Guice 2 进行 Java 开发 在我的网络应用程序中 我有一个转换器注册表 可以即时转换为某种类型 转换器描述如下 public class StringToBoolean im
  • 内部存储的安全性如何?

    我需要的 对于 Android 我需要永久保存数据 但也能够编辑 并且显然是读取 它 用户不应访问此数据 它可以包含诸如高分之类的内容 用户不得对其进行编辑 我的问题 我会 并且已经 使用过Internal Storage 但我不确定它实际
  • GWT 2.3 开发模式 - 托管模式 JSP 编译似乎不使用 java 1.5 兼容性

    无法编译 JSP 类 生成的 servlet 错误 DefaultMessage 上次更新 0 日期 中 0 时间 HH mm ss z 语法 错误 注释仅在源级别为 1 5 时可用 在尝试以开发模式在 Web 浏览器中打开我的 gwt 模
  • XCode 4.5 给我“SenTestingKit/SenTestKit.h”文件未找到,但适用于 4.4.1

    我刚刚安装了 XCode 4 5 它在我现有的项目之一上给了我一个 SenTestingKit SenTestingKit h 文件未找到错误 此错误仅发生在 XCode 4 5 中 但它在 4 4 1 上编译正常 我已经检查过SenTes
  • Java实现累加器类,提供Collector

    A Collector具有三种通用类型 public interface Collector
  • 以编程方式在 App Store 上运行搜索?

    是否可以从我的应用程序中打开 App Store 应用程序并运行搜索 我想看看是否有一个 appstore 类型的 URL 可以使用 就像 mailto 和 sms 分别打开邮件和短信一样 有谁知道这是否可能 编辑 更多信息 我一直在尝试使
  • java库维护数据库结构

    我的应用程序一直在开发 所以偶尔 当版本升级时 需要创建 更改 删除一些表 修改一些数据等 通常需要执行一些sql代码 是否有一个 Java 库可用于使我的数据库结构保持最新 通过分析类似 db structure version 信息并执
  • 将 UIButton 中的图像缩放到 AspectFit?

    我想将图像添加到 UIButton 并且还想缩放图像以适合 UIButton 使图像变小 请告诉我该怎么做 这是我尝试过的 但它不起作用 将图像添加到按钮并使用setContentMode self itemImageButton setI
  • Hamcrest Matchers - 断言列表类型

    问题 我目前正在尝试使用 Hamcrest Matchers 来断言返回的列表类型是特定类型 例如 假设我的服务调用返回以下列表 List
  • iOS 视图控制器内存在被关闭后未释放

    当用户单击按钮时 它会显示一个带有两个视图控制器的新选项卡栏视图控制器 我是这样做的 ACLevelDownloadController dvc ACLevelDownloadController alloc initWithNibName
  • Android:无法发送http post

    我一直在绞尽脑汁试图弄清楚如何在 Android 中发送 post 方法 这就是我的代码的样子 public class HomeActivity extends Activity implements OnClickListener pr
  • 如何重新启动死线程? [复制]

    这个问题在这里已经有答案了 有哪些不同的可能性可以带来死线程回到可运行状态 如果您查看线程生命周期图像 就会发现一旦线程终止 您就无法返回到新位置 So 没有办法将死线程恢复到可运行状态 相反 您应该创建一个新的 Thread 实例
  • Java中HashMap和ArrayList的区别?

    在爪哇 ArrayList and HashMap被用作集合 但我不明白我们应该在哪些情况下使用ArrayList以及使用时间HashMap 他们两者之间的主要区别是什么 您具体询问的是 ArrayList 和 HashMap 但我认为要完
  • 泛型、数组和 ClassCastException

    我想这里一定发生了一些我不知道的微妙事情 考虑以下 public class Foo

随机推荐