2014-06-12 18 views
1

我有很多使用PBEWithMD5AndDES算法編碼的字符串。 現在我將代碼移植到Objective-C中。但我無法正確解密數據。 我正在使用所有寫入here的代碼。 我用這個功能在Java中用於加密/解密數據:iOS和Android中的PBEWithMD5AndDES

@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 strEnc)是"6_O6V3327e5vnNpMB7_wNg"

正如我理解,我可以使用此類加密/解密數據在IOS使用OpenSSL:

- (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庫。

回答

1

我對你有同樣的問題;但我想我解決它;

PBEWithMD5AndDES Encryption in iOS我用它來加密ios中的字符串;我修改加密鹽:

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的encry鹽:

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

的IOS的鹽的值必須0-128之間(因爲它的類型是unsigned char和Android的鹽是字節型的)

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中的salt不同;所以這就是爲什麼你在android和ios中獲得不同的base64字符串;

+0

感謝您的回答。我儘快檢查。很多時間過去了...無論如何,謝謝。 – Vyacheslav