PBEWithMD5AndDES在iOS和Android

我有很多使用PBEWithMD5AndDESalgorithm的Java编码的string。 现在我将代码移植到Objective-C中。 但是我不能正确解密数据。 我正在使用这里写的所有代码。 我在Java中使用这个函数来encryption/解密数据:

@Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.amain); try { viewKey(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); Log.d("checkingthevalue",e.toString()); } } private void viewKey() { // TODO Auto-generated method stub String pass = "password"; String testStr = "TheSecretString"; final byte[] SALT = { (byte) 0xaa, (byte) 0xaa, (byte) 0xce, (byte) 0xce, (byte) 0xaa, (byte) 0xaa, (byte) 0xce, (byte) 0xce, }; try{ SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES"); SecretKey key = keyFactory.generateSecret(new PBEKeySpec(pass.toCharArray())); Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES"); pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(SALT, 20)); String strEnc = base64Encode(pbeCipher.doFinal(testStr.getBytes("UTF-8"))); Log.d("ViewKey", "strEnc :: " + strEnc); }catch (Exception e) { Log.d("ViewKey","ERROR"); } } private static String base64Encode(byte[] bytes) { final int asd = Base64.URL_SAFE | Base64.NO_PADDING | Base64.NO_WRAP ; return Base64.encodeToString(bytes,asd); } 

结果string( String strEnc )是"6_O6V3327e5vnNpMB7_wNg"

据我所知,我可以使用这个类来使用OpenSSL在iOS中encryption/解密数据:

  - (void)viewDidLoad { [super viewDidLoad]; [self testSSL3]; } -(void) testSSL{ PS_PBEwithMD5andDes *PBE = [[PS_PBEwithMD5andDes alloc] init]; NSString *password = @"password"; NSString *message = @"TheSecretString"; int it = 20; { NSData *inData = [message dataUsingEncoding:NSUTF8StringEncoding]; NSData *encData = [PBE encryptPBEWithMD5AndDESData:inData password:password iterations:it]; NSString *encString = [encData base64EncodedString]; NSLog(@":: %@",encString); } } 

PS_PBEwithMD5andDes类:

 PS_PBEwithMD5andDes.h // // PS_PBEwithMD5andDes.h // // // Created by Admin on 11.06.14. // Copyright (c) 2014 PS. All rights reserved. // #import <Foundation/Foundation.h> @interface PS_PBEwithMD5andDes : NSObject - (NSData *)encryptPBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password iterations:(int)iterations; - (NSData *)decryptPBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password iterations:(int)iterations; - (NSData *)encodePBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password direction:(int)direction iterations:(int)iterations; @end PS_PBEwithMD5andDes.m // // PS_PBEwithMD5andDes.m // // // Created by Admin on 11.06.14. // Copyright (c) 2014 PS. All rights reserved. // #import "PS_PBEwithMD5andDes.h" #import "libs/include_openssl/openssl/md5.h" #import "libs/include_openssl/openssl/sha.h" #import "libs/include_openssl/openssl/x509.h" #import "libs/include_openssl/openssl/err.h" #import "libs/include_openssl/openssl/evp.h" @implementation PS_PBEwithMD5andDes - (NSData *)encryptPBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password iterations:(int)iterations{ return [self encodePBEWithMD5AndDESData:inData password:password direction:1 iterations:iterations]; } - (NSData *)decryptPBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password iterations:(int)iterations { return [self encodePBEWithMD5AndDESData:inData password:password direction:0 iterations:iterations]; } - (NSData *)encodePBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password direction:(int)direction iterations:(int)iterations { // Change salt and number of iterations for your project !!! static const char gSalt[] = { (unsigned char) 0xaa, (unsigned char) 0xaa, (unsigned char) 0xce, (unsigned char) 0xce, (unsigned char) 0xaa, (unsigned char) 0xaa, (unsigned char) 0xce, (unsigned char) 0xce }; unsigned char *salt = (unsigned char *)gSalt; int saltLen = strlen(gSalt); EVP_CIPHER_CTX cipherCtx; unsigned char *mResults; // allocated storage of results int mResultsLen = 0; const char *cPassword = [password UTF8String]; unsigned char *mData = (unsigned char *)[inData bytes]; int mDataLen = [inData length]; SSLeay_add_all_algorithms(); X509_ALGOR *algorithm = PKCS5_pbe_set(NID_pbeWithMD5AndDES_CBC, iterations, salt, saltLen); memset(&cipherCtx, 0, sizeof(cipherCtx)); if (algorithm != NULL) { EVP_CIPHER_CTX_init(&(cipherCtx)); if (EVP_PBE_CipherInit(algorithm->algorithm, cPassword, strlen(cPassword), algorithm->parameter, &(cipherCtx), direction)) { EVP_CIPHER_CTX_set_padding(&cipherCtx, 1); int blockSize = EVP_CIPHER_CTX_block_size(&cipherCtx); int allocLen = mDataLen + blockSize + 1; // plus 1 for null terminator on decrypt mResults = (unsigned char *)OPENSSL_malloc(allocLen); unsigned char *in_bytes = mData; int inLen = mDataLen; unsigned char *out_bytes = mResults; int outLen = 0; int outLenPart1 = 0; if (EVP_CipherUpdate(&(cipherCtx), out_bytes, &outLenPart1, in_bytes, inLen)) { out_bytes += outLenPart1; int outLenPart2 = 0; if (EVP_CipherFinal(&(cipherCtx), out_bytes, &outLenPart2)) { outLen += outLenPart1 + outLenPart2; mResults[outLen] = 0; mResultsLen = outLen; } } else { unsigned long err = ERR_get_error(); ERR_load_crypto_strings(); ERR_load_ERR_strings(); char errbuff[256]; errbuff[0] = 0; ERR_error_string_n(err, errbuff, sizeof(errbuff)); NSLog(@"OpenSLL ERROR:\n\tlib:%d\n\tfunction:%d\n\treason:%d\n", ERR_lib_error_string(err), ERR_func_error_string(err), ERR_reason_error_string(err)); ERR_free_strings(); } NSData *encryptedData = [NSData dataWithBytes:mResults length:mResultsLen]; return encryptedData; } } return nil; } @end 

在iOS中的结果( NSString *encString )是@"h1wZWAuxI71flGJKGcwCOg=="

总结,结果:

在Java中: "6_O6V3327e5vnNpMB7_wNg"在Objective-C中: @"h1wZWAuxI71flGJKGcwCOg=="

问题:1)。 为什么他们给出不同的结果? 2)。 如何解决问题? 3)。 为什么在Objective-C的所有情况下,最后2个字母是"==" ? 在Objective-C中使用OpenSSL库。

我和你有同样的问题,但我想我解决它;

PBEWithMD5AndDES在iOS中的encryption我使用这个来encryptionios中的string; 我修改encryption盐到:

 static const char gSalt[] = { (unsigned char)0x18, (unsigned char)0x79, (unsigned char)0x6D, (unsigned char)0x6D, (unsigned char)0x35, (unsigned char)0x3A, (unsigned char)0x6A, (unsigned char)0x60, (unsigned char)0x00 }; 

然后我将android的encryption盐设置为:

 private static byte[] salt = new byte[] {24, 121, 109, 109, 53, 58, 106, 96}; 

ios的salt的值必须在0-128之间(因为它的types是unsigned char,android的salt是字节型的)

 final byte[] SALT = { (byte) 0xaa, (byte) 0xaa, (byte) 0xce, (byte) 0xce, (byte) 0xaa, (byte) 0xaa, (byte) 0xce, (byte) 0xce, }; 

这是你的盐,0xaa是170> 128,所以当你把它转换为字节时,值被改变; 所以你在android中的salt与ios中的盐是不同的; 所以这就是为什么你在android和ios中获得不同的base64string;