Android、iPhone和Java三个平台一致的加密方法

最佳安全实践:在 Java 和 Android 中使用 AES 进行对称加密:第2部分:AES-CBC + HMAC 我们演示了使用密码分组链接(CBC)的 AES 和使用 HMAC 的 Encrypt-then-MAC 架构提供了我们希望从加密协议中看到的所有理想的安全属性:保密性、完整性和真实性。可以看出,仅仅使用了 GCM,协议就变得复杂了。但是,这些原语通常在所有 Java/Android 环境中都可用,因此它可能是你唯一的选择。使用 16 字节随机初始化向量(使用强PRNG)使用 128 位以上的 MAC 长度(HMAC-SHA256 输出 256 位)使用 Encrypt-then-Mac。 阅读详情

转:http://developer.51cto.com/art/201311/419158_all.htm

先前一直在做安卓,最近要开发iPhone客户端,这其中遇到的最让人纠结的要属Java、Android和iPhone三个平台加解密不一致的问 题。因为手机端后台通常是用JAVA开发的Web Service,Android和iPhone客户端调用同样的Web Service接口,为了数据安全考虑,要对数据进行加密。头疼的问题就来了,很难编写出一套加密程序,在3个平台间加解密的结果一致,总不能为 Android和iPhone两个客户端各写一套Web Service接口吧?我相信还会有很多朋友为此困惑,在此分享一套3DES加密程序,能够实现Java、Android和iPhone三个平台加解密一 致。

首先是JAVA端的加密工具类,它同样适用于Android端,无需任何修改,即可保证Java与Android端的加解密一致,并且中文不会乱码。

双击代码全选

  1. package org.liuyq.des3;  
  2.         
  3. import java.security.Key;  
  4.         
  5. import javax.crypto.Cipher;  
  6. import javax.crypto.SecretKeyFactory;  
  7. import javax.crypto.spec.DESedeKeySpec;  
  8. import javax.crypto.spec.IvParameterSpec;  
  9.         
  10. /** 
  11.   * 3DES加密工具类 
  12.   *  
  13.   * @author liufeng  
  14.   * @date 2012-10-11 
  15.   */ 
  16. public class Des3 {  
  17.      // 密钥  
  18.      private final static String secretKey = "liuyunqiang@lx100$#365#$" ;  
  19.      // 向量  
  20.      private final static String iv = "01234567" ;  
  21.      // 加解密统一使用的编码方式  
  22.      private final static String encoding = "utf-8" ;  
  23.         
  24.      /** 
  25.       * 3DES加密 
  26.       *  
  27.       * @param plainText 普通文本 
  28.       * @return 
  29.       * @throws Exception  
  30.       */ 
  31.      public static String encode(String plainText) throws Exception {  
  32.          Key deskey = null ;  
  33.          DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());  
  34.          SecretKeyFactory keyfactory = SecretKeyFactory.getInstance( "desede" );  
  35.          deskey = keyfactory.generateSecret(spec);  
  36.         
  37.          Cipher cipher = Cipher.getInstance( "desede/CBC/PKCS5Padding" );  
  38.          IvParameterSpec ips = new IvParameterSpec(iv.getBytes());  
  39.          cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);  
  40.          byte [] encryptData = cipher.doFinal(plainText.getBytes(encoding));  
  41.          return Base64.encode(encryptData);  
  42.      }  
  43.         
  44.      /** 
  45.       * 3DES解密 
  46.       *  
  47.       * @param encryptText 加密文本 
  48.       * @return 
  49.       * @throws Exception 
  50.       */ 
  51.      public static String decode(String encryptText) throws Exception {  
  52.          Key deskey = null ;  
  53.          DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());  
  54.          SecretKeyFactory keyfactory = SecretKeyFactory.getInstance( "desede" );  
  55.          deskey = keyfactory.generateSecret(spec);  
  56.          Cipher cipher = Cipher.getInstance( "desede/CBC/PKCS5Padding" );  
  57.          IvParameterSpec ips = new IvParameterSpec(iv.getBytes());  
  58.          cipher.init(Cipher.DECRYPT_MODE, deskey, ips);  
  59.         
  60.          byte [] decryptData = cipher.doFinal(Base64.decode(encryptText));  
  61.         
  62.          return new String(decryptData, encoding);  
  63.      }  
  64. } 

上面的加密工具类会使用到Base64这个类,该类的源代码如下:

双击代码全选

  1. package org.liuyq.des3;  
  2. import java.io.ByteArrayOutputStream;  
  3. import java.io.IOException;  
  4. import java.io.OutputStream;  
  5.         
  6. /** 
  7.   * Base64编码工具类 
  8.   *  
  9.   * @author liufeng  
  10.   * @date 2012-10-11 
  11.   */ 
  12. public class Base64 {  
  13.      private static final char [] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" .toCharArray();  
  14.         
  15.      public static String encode( byte [] data) {  
  16.          int start = 0 ;  
  17.          int len = data.length;  
  18.          StringBuffer buf = new StringBuffer(data.length * 3 / 2 );  
  19.         
  20.          int end = len - 3 ;  
  21.          int i = start;  
  22.          int n = 0 ;  
  23.         
  24.          while (i <= end) {  
  25.              int d = (((( int ) data[i]) & 0x0ff ) << 16 ) | (((( int ) data[i + 1 ]) & 0x0ff ) << 8 ) | ((( int ) data[i + 2 ]) & 0x0ff );  
  26.         
  27.              buf.append(legalChars[(d >> 18 ) & 63 ]);  
  28.              buf.append(legalChars[(d >> 12 ) & 63 ]);  
  29.              buf.append(legalChars[(d >> 6 ) & 63 ]);  
  30.              buf.append(legalChars[d & 63 ]);  
  31.         
  32.              i += 3 ;  
  33.         
  34.              if (n++ >= 14 ) {  
  35.                  n = 0 ;  
  36.                  buf.append( " " );  
  37.              }  
  38.          }  
  39.         
  40.          if (i == start + len - 2 ) {  
  41.              int d = (((( int ) data[i]) & 0x0ff ) << 16 ) | (((( int ) data[i + 1 ]) & 255 ) << 8 );  
  42.         
  43.              buf.append(legalChars[(d >> 18 ) & 63 ]);  
  44.              buf.append(legalChars[(d >> 12 ) & 63 ]);  
  45.              buf.append(legalChars[(d >> 6 ) & 63 ]);  
  46.              buf.append( "=" );  
  47.          } else if (i == start + len - 1 ) {  
  48.              int d = ((( int ) data[i]) & 0x0ff ) << 16 ;  
  49.         
  50.              buf.append(legalChars[(d >> 18 ) & 63 ]);  
  51.              buf.append(legalChars[(d >> 12 ) & 63 ]);  
  52.              buf.append( "==" );  
  53.          }  
  54.         
  55.          return buf.toString();  
  56.      }  
  57.         
  58.      private static int decode( char c) {  
  59.          if (c >= 'A' && c <= 'Z' )  
  60.              return (( int ) c) - 65 ;  
  61.          else if (c >= 'a' && c <= 'z' )  
  62.              return (( int ) c) - 97 + 26 ;  
  63.          else if (c >= '0' && c <= '9' )  
  64.              return (( int ) c) - 48 + 26 + 26 ;  
  65.          else 
  66.              switch (c) {  
  67.              case '+' :  
  68.                  return 62 ;  
  69.              case '/' :  
  70.                  return 63 ;  
  71.              case '=' :  
  72.                  return 0 ;  
  73.              default :  
  74.                  throw new RuntimeException( "unexpected code: " + c);  
  75.              }  
  76.      }  
  77.         
  78.      /** 
  79.       * Decodes the given Base64 encoded String to a new byte array. The byte array holding the decoded data is returned. 
  80.       */ 
  81.         
  82.      public static byte [] decode(String s) {  
  83.         
  84.          ByteArrayOutputStream bos = new ByteArrayOutputStream();  
  85.          try {  
  86.              decode(s, bos);  
  87.          } catch (IOException e) {  
  88.              throw new RuntimeException();  
  89.          }  
  90.          byte [] decodedBytes = bos.toByteArray();  
  91.          try {  
  92.              bos.close();  
  93.              bos = null ;  
  94.          } catch (IOException ex) {  
  95.              System.err.println( "Error while decoding BASE64: " + ex.toString());  
  96.          }  
  97.          return decodedBytes;  
  98.      }  
  99.         
  100.      private static void decode(String s, OutputStream os) throws IOException {  
  101.          int i = 0 ;  
  102.         
  103.          int len = s.length();  
  104.         
  105.          while ( true ) {  
  106.              while (i < len && s.charAt(i) <= ' ' )  
  107.                  i++;  
  108.         
  109.              if (i == len)  
  110.                  break ;  
  111.         
  112.              int tri = (decode(s.charAt(i)) << 18 ) + (decode(s.charAt(i + 1 )) << 12 ) + (decode(s.charAt(i + 2 )) << 6 ) + (decode(s.charAt(i + 3 )));  
  113.         
  114.              os.write((tri >> 16 ) & 255 );  
  115.              if (s.charAt(i + 2 ) == '=' )  
  116.                  break ;  
  117.              os.write((tri >> 8 ) & 255 );  
  118.              if (s.charAt(i + 3 ) == '=' )  
  119.                  break ;  
  120.              os.write(tri & 255 );  
  121.         
  122.              i += 4 ;  
  123.          }  
  124.      }  
  125. } 

接下来是iPhone端的加密程序,当然是用Ojbective-C写的3DES加密程序,源代码如下: 双击代码全选

  1. //  
  2. //  DES3Util.h  
  3. //  lx100-gz  
  4. //  
  5. //  Created by  柳峰 on 12-10-10.  
  6. //  Copyright 2012 http://blog.youkuaiyun.com/lyq8479. All rights reserved.  
  7. //  
  8.         
  9. #import <Foundation/Foundation.h>  
  10.         
  11.         
  12. @interface DES3Util : NSObject {  
  13.         
  14. }  
  15.         
  16. // 加密方法  
  17. + (NSString*)encrypt:(NSString*)plainText;  
  18.         
  19. // 解密方法  
  20. + (NSString*)decrypt:(NSString*)encryptText;  
  21.         
  22. @end 

双击代码全选

  1. //  
  2. //  DES3Util.m  
  3. //  lx100-gz  
  4. //  
  5. //  Created by  柳峰 on 12-9-17.  
  6. //  Copyright 2012 http://blog.youkuaiyun.com/lyq8479. All rights reserved.  
  7. //  
  8.         
  9. #import "DES3Util.h"  
  10. #import <CommonCrypto/CommonCryptor.h>  
  11. #import "GTMBase64.h"  
  12.         
  13. #define gkey            @"liuyunqiang@lx100$#365#$"  
  14. #define gIv             @"01234567"  
  15.         
  16. @implementation DES3Util  
  17.         
  18. // 加密方法  
  19. + (NSString*)encrypt:(NSString*)plainText {  
  20.      NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];  
  21.      size_t plainTextBufferSize = [data length];  
  22.      const void *vplainText = (const void *)[data bytes];  
  23.             
  24.      CCCryptorStatus ccStatus;  
  25.      uint8_t *bufferPtr = NULL;  
  26.      size_t bufferPtrSize = 0;  
  27.      size_t movedBytes = 0;  
  28.             
  29.      bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);  
  30.      bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));  
  31.      memset((void *)bufferPtr, 0x0, bufferPtrSize);  
  32.             
  33.      const void *vkey = (const void *) [gkey UTF8String];  
  34.      const void *vinitVec = (const void *) [gIv UTF8String];  
  35.             
  36.      ccStatus = CCCrypt(kCCEncrypt,  
  37.                         kCCAlgorithm3DES,  
  38.                         kCCOptionPKCS7Padding,  
  39.                         vkey,  
  40.                         kCCKeySize3DES,  
  41.                         vinitVec,  
  42.                         vplainText,  
  43.                         plainTextBufferSize,  
  44.                         (void *)bufferPtr,  
  45.                         bufferPtrSize,  
  46.                         &movedBytes);  
  47.             
  48.      NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];  
  49.      NSString *result = [GTMBase64 stringByEncodingData:myData];  
  50.      return result;  
  51. }  
  52.         
  53. // 解密方法  
  54. + (NSString*)decrypt:(NSString*)encryptText {  
  55.      NSData *encryptData = [GTMBase64 decodeData:[encryptText dataUsingEncoding:NSUTF8StringEncoding]];  
  56.      size_t plainTextBufferSize = [encryptData length];  
  57.      const void *vplainText = [encryptData bytes];  
  58.             
  59.      CCCryptorStatus ccStatus;  
  60.      uint8_t *bufferPtr = NULL;  
  61.      size_t bufferPtrSize = 0;  
  62.      size_t movedBytes = 0;  
  63.             
  64.      bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);  
  65.      bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));  
  66.      memset((void *)bufferPtr, 0x0, bufferPtrSize);  
  67.             
  68.      const void *vkey = (const void *) [gkey UTF8String];  
  69.      const void *vinitVec = (const void *) [gIv UTF8String];  
  70.             
  71.      ccStatus = CCCrypt(kCCDecrypt,  
  72.                         kCCAlgorithm3DES,  
  73.                         kCCOptionPKCS7Padding,  
  74.                         vkey,  
  75.                         kCCKeySize3DES,  
  76.                         vinitVec,  
  77.                         vplainText,  
  78.                         plainTextBufferSize,  
  79.                         (void *)bufferPtr,  
  80.                         bufferPtrSize,  
  81.                         &movedBytes);  
  82.             
  83.      NSString *result = [[[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bufferPtr   
  84.                                  length:(NSUInteger)movedBytes] encoding:NSUTF8StringEncoding] autorelease];  
  85.      return result;  
  86. }  
  87.         
  88. @end 

iPhone端的加密工具类中引入了“GTMBase64.h”,这是iOS平台的Base64编码工具类,见附件

好了,赶紧试一下吧,JAVA,Android和iPhone三个平台的加密不一致问题是不是解决了呢?以上为3DES加密,也可将其改为AES加密。 其实,对此问题,还有一种更好的实现方式,那就是用C语言写一套加密程序,这样在iOS平台是可以直接使用C程序的,而在Java和Android端通过 JNI去调用C语言编写的加密方法,这是不是就实现了3个平台调用同一套加密程序呢?


实现前端、Android、iPhone和Java后端四个平台一致的加密工具 NULL 博文链接:https://aaron7524.iteye.com/blog/2090075 立即下载

相关推荐

android ios java后台通用DES base64加密

android ios java后台通用DES base64加密

ios java aes加密_AES加密/解密 IOS 端,JAVA端 通用,不限明文字符长度

测试发现,当前问题是:明文字符长度<=15时, IOS 端的 AES 加密结果和 JAVA 端是一样的明文字符长度>15时, IOS 的加密和 JAVA 的加密是不同的, 但都可以在各自语言中成功解密解决办法就不说了,直接上代码-(NSData*)AESOperation:(CCOperation)operationkey:(NSString*)keyiv:(NSString...

weixin_39581652的博客 300

ios与android与java通用的AES加解密

ios与android与java通用的AES加解密,亲测可用。

iOS JAVA互通AES加解密实现

iOS JAVA互通AES加解密实现

booyoung的博客 1776

BDD测试之Behave使用入门

BDD测试(Behavior-Driven Development Testing)是一种基于“行为驱动开发”(BDD)理念。

想要成为酷盖但是失败的小明 581

如何理解Fourier Neural Operator (FNO)

2022年Nvidia发表在arXiv上的的FourcastNet作为几乎是最早的一篇气象大模型的工作(之前Google Research的MetNet主要还是对于降水的预报)。除了Transformer的backbone之外,使用到了2021年发表在ICLR上的Fourier Neural Operator。为了更好的理解模型的理论基础,可以详细学习一下以及他的前期工作GNOFNO作者对这两篇文章的解析blog。

momo的博客 1万+

3DES加密—java/OC

移动开发中遇到的最让人纠结的要属Java、Android和iPhone三个平台加解密不一致的问题。因为手机端后台通常是用JAVA开发的Web Service,Android和iPhone客户端调用同样的Web Service接口,为了数据安全考虑,要对数据进行加密。头疼的问题就来了,很难编写出一套加密程序,在3个平台间加解密的结果一致,总不能为Android和iPhone两个客户端各写一套Web S

MN1107 658

Latext安装(二)WinEdt安装+激活教程

常用的LaTeX安装方案是TeXLive + WinEdt。TeXLive 是LaTeX的运行环境,而 WinEdt 则是编写LaTeX文档的编辑器。安装好TexLive之后,再安装WinEdt。这里介绍的是WinEdt的安装和激活教程。

j_l_sheng的博客 4万+

android_iphone和java三个平台一致的加密方法_Android、iPhone和Java三个平台一致的加密方法...

先前一直在做安卓,最近要开发iPhone客户端,这其中遇到的最让人纠结的要属Java、Android和iPhone三个平台加解密不一致的问 题。因为手机端后台通常是用JAVA开发的Web Service,Android和iPhone客户端调用同样的Web Service接口,为了数据安全考虑,要对数据进行加密。头疼的问题就来了,很难编写出一套加密程序,在3个平台间加解密的结果一致,总不能为 And...

weixin_30122219的博客 136

把 LangGraph 当“工作流引擎”用:与传统 BPM 的差异与融合策略

首先,我们来回顾一下有限状态机(FSM)的基本定义——一个 FSM 可以用一个五元组MQΣδq0FMQΣδq0​FQQQ有限状态集合,包含 FSM 所有可能的状态;Σ\SigmaΣ有限输入字母表,包含 FSM 所有可能的输入;δ\deltaδ状态转移函数,定义了 FSM 从当前状态q∈Qq \in Qq∈Q接收输入σ∈Σσ∈Σ后,转移到的下一个状态q′∈Qq' \in Qq′∈Q,即δQ×Σ→QδQ×Σ→Q。

AI 原生应用开发的博客 227

【ArcGIS微课1000例】0118:一文讲清楚tif(geotiff)栅格数据格式

TIFF(Tagged Image File Format)是一种常见的图像文件格式,它被广泛用于存储和传输各种类型的图像数据。图像存储:TIFF格式可以存储多通道的位图图像,包括灰度图、彩色图和透明度图等。它支持不同的像素深度,可以是8位、16位、24位或32位等。因此,TIFF格式非常适合存储高质量的图像数据,包括照片、卫星图像、医学影像等。无损压缩:TIFF格式支持无损压缩,这意味着图像可以被压缩而无需损失任何像素信息。这种压缩方式可以减小文件大小,而不会降低图像的质量。

智慧空间实验室 2822

android_iphone和java三个平台一致的加密方法_Android、iPhone和Java三个平台一致的加密方法(1)...

先前一直在做安卓,最近要开发iPhone客户端,这其中遇到的最让人纠结的要属Java、Android和iPhone三个平台加解密不一致的问 题。因为手机端后台通常是用JAVA开发的Web Service,Android和iPhone客户端调用同样的Web Service接口,为了数据安全考虑,要对数据进行加密。头疼的问题就来了,很难编写出一套加密程序,在3个平台间加解密的结果一致,总不能为 An...

weixin_35896668的博客 144

G120变频器抱闸逻辑在提升机上应用

一、前言: 对于提升机、起重机、堆垛机、升降机等提升机构,负载为位能性负载,在设备启动和停止阶段,由于重物作用,可能会出现“溜车”现象、控制变频器与电机抱闸时许可以解决此问题 使用具有矢量控制功能的变频器 二、参数设置 抱闸控制时序: 启动: 1、变频器接收到启动命令时-----输出电流对电机进行励磁,经过P346电机励磁时间(==丹佛斯 设置启动电流延时0.5S)------达到一定的转矩 2、变频器输出开抱闸命令,经过P1216延时打开抱闸时间(==PLC延时控制打开抱闸) 注意:抱闸

fenglingxicao的博客 1万+

android_iphone和java三个平台一致的加密方法_Android、iPhone和Java三个平台一致的加密工具...

import java.security.Key;import javax.crypto.Cipher;import javax.crypto.SecretKeyFactory;import javax.crypto.spec.DESedeKeySpec;import javax.crypto.spec.IvParameterSpec;/*** 3DES加密工具类** @author liufen...

weixin_35343226的博客 110

​​光流结合深度学习实现物体运动方向判断

光流计算:提取每一帧视频中像素的运动信息,生成光流图。光流特征提取:通过特定的预处理,将光流图转换为深度学习模型可用的输入格式。深度学习模型设计:构建一个卷积神经网络(CNN)或其他适合的深度学习架构,利用光流特征进行运动方向分类。模型训练与推理:对网络进行训练并使用训练好的模型判断运动方向。光流与深度学习结合的运动方向判断技术在多个领域具有广泛的应用前景。通过光流提取像素级动态信息,并利用深度学习模型学习高层次特征,可以实现高精度的运动检测与方向判断。

matlab_python22的博客 321

自助结账商品检测(Scanned Item Detection)——基于YOLOv8的RPC数据集实战

RPC数据集是由中国科学院自动化研究所发布的零售商品结账检测公开数据集,广泛用于自助结账和零售场景下的目标检测与识别。YOLOv8是YOLO系列最新版本,由Ultralytics推出,继承了YOLO家族的高效快速和高准确性,适用于实时检测场景。本文系统介绍了基于YOLOv8的RPC数据集自助结账商品检测方案,涵盖数据准备、训练、推理及UI界面设计。未来,可结合多模态感知、RFID融合技术,打造更加智能和稳定的自助结账系统。

YOLO 252
上一篇: 数据库关于group by 两个或以上条件的分析
下一篇: Android开发工具的下载
lcathm
博客等级 码龄18年 37粉丝 44原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值