我必须加密Objective C中的字符串。加密方案是3DES / CBC / PKCS5填充,我必须在Objective C中转换这个Java代码:
public class MessageEncrypt {
public String encryptString(String message, String seckey) throws Exception{
byte[] encData = encrypt(message, seckey);
return this.getHexString(encData, "");
}
public String decryptString(String message, String seckey) throws Exception{
return decrypt(this.getBArray(message), seckey);
}
private byte[] encrypt(String message, String seckey) throws Exception {
final MessageDigest md = MessageDigest.getInstance("md5");
final byte[] digestOfPassword = md.digest(seckey.getBytes("utf-8"));
final byte[] keyBytes = acopyof(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
final Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
final byte[] plainTextBytes = message.getBytes("utf-8");
final byte[] cipherText = cipher.doFinal(plainTextBytes);
// final String encodedCipherText = new sun.misc.BASE64Encoder()
// .encode(cipherText);
return cipherText;
}
private String decrypt(byte[] message, String seckey) throws Exception {
final MessageDigest md = MessageDigest.getInstance("md5");
final byte[] digestOfPassword = md.digest(seckey.getBytes("utf-8"));
final byte[] keyBytes = acopyof(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
final Cipher decipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
decipher.init(Cipher.DECRYPT_MODE, key, iv);
final byte[] plainText = decipher.doFinal(message);
return new String(plainText, "UTF-8");
}
private String getHexString(byte[] barray, String delim) {
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < barray.length; i++) {
int ii = barray[i] & 0xFF;
String bInt = Integer.toHexString(ii);
if (ii < 16) {
bInt = "0" + bInt.toUpperCase();
}
buffer.append(bInt);
if (i < barray.length - 1) {
buffer.append(delim);
}
}
return buffer.toString().toUpperCase();
}
private byte[] getBArray(String bString) {
byte[] retBytes;
if (bString.length() % 2 != 0) {
return new byte[0];
}
retBytes = new byte[bString.length() / 2];
for (int i = 0; i < bString.length() / 2; i++) {
retBytes[i] = (byte) ((Character.digit(bString.charAt(2 * i), 16) << 4) + Character.digit(bString.charAt(2 * i + 1), 16));
}
return retBytes;
}
public static byte[] acopyof(byte[] orig, int newlength){
byte[] copya = new byte[newlength];
for(int i=0;i< orig.length;i++){
copya[i]=orig[i];
}
for(int i=orig.length;i<newlength;i++){
copya[i]=0x0;
}
return copya;
}
}
目标C代码:
+(NSString*)doCipher:(NSString*)sTextIn:(CCOperation)encryptOrDecrypt {
NSMutableData *dTextIn;
if (encryptOrDecrypt == kCCDecrypt)
{
//TODO
}
else
{
dTextIn = [[sTextIn dataUsingEncoding: NSUTF8StringEncoding]mutableCopy];
}
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
// uint8_t ivkCCBlockSize3DES;
bufferPtrSize = ([dTextIn length] + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
// Initialization vector; in this case 8 bytes.
uint8_t iv[kCCBlockSize3DES];
memset((void *) iv, 0x0, (size_t) sizeof(iv));
NSString *key = [@"MY_KEY_HERE" MD5];
NSMutableData *_keyData = [[key dataUsingEncoding:NSUTF8StringEncoding]mutableCopy];
unsigned char *bytePtr = (unsigned char *)[_keyData bytes];
[_keyData setLength:24];
unsigned char *bytePtr1 = (unsigned char *)[_keyData bytes];
ccStatus = CCCrypt(encryptOrDecrypt, // CCoperation op
kCCAlgorithm3DES, // CCAlgorithm alg
kCCOptionPKCS7Padding, // CCOptions
[_keyData bytes], // const void *key
kCCKeySize3DES, // 3DES key size length 24 bit
iv, //const void *iv,
[dTextIn bytes], // const void *dataIn
[dTextIn length], // size_t dataInLength
(void *)bufferPtr, // void *dataOut
bufferPtrSize, // size_t dataOutAvailable
&movedBytes); // size_t *dataOutMoved
if (ccStatus == kCCParamError) return @"PARAM ERROR";
else if (ccStatus == kCCBufferTooSmall) return @"BUFFER TOO SMALL";
else if (ccStatus == kCCMemoryFailure) return @"MEMORY FAILURE";
else if (ccStatus == kCCAlignmentError) return @"ALIGNMENT";
else if (ccStatus == kCCDecodeError) return @"DECODE ERROR";
else if (ccStatus == kCCUnimplemented) return @"UNIMPLEMENTED";
NSString *result;
if (encryptOrDecrypt == kCCDecrypt)
{
result = [[[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes] encoding:NSUTF8StringEncoding] autorelease];
}
else
{
NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
result = [NSString dataToHex:myData];
}
return result;
}
不明白为什么我会得到不同的结果。有什么想法吗?
答案 0 :(得分:0)
我做到了。解决方案:
Java代码:
public class MessageEncrypt {
public String encryptString(String message, String seckey) throws Exception{
byte[] encData = encrypt(message, seckey);
return Base64.encodeToString(encData, Base64.DEFAULT);
}
public String decryptString(String message, String seckey) throws Exception{
byte[] encData= Base64.decode(message, Base64.DEFAULT);
return decrypt(encData, seckey);
}
private byte[] encrypt(String message, String seckey) throws Exception {
final MessageDigest md = MessageDigest.getInstance("md5");
final byte[] digestOfPassword = md.digest(seckey.getBytes("utf-8"));
final byte[] keyBytes = acopyof(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
final Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
final byte[] plainTextBytes = message.getBytes("utf-8");
final byte[] cipherText = cipher.doFinal(plainTextBytes);
return cipherText;
}
private String decrypt(byte[] message, String seckey) throws Exception {
final MessageDigest md = MessageDigest.getInstance("md5");
final byte[] digestOfPassword = md.digest(seckey.getBytes("utf-8"));
final byte[] keyBytes = acopyof(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
final Cipher decipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
decipher.init(Cipher.DECRYPT_MODE, key, iv);
final byte[] plainText = decipher.doFinal(message);
return new String(plainText, "UTF-8");
}
public byte[] acopyof(byte[] orig, int newlength){
byte[] copya = new byte[newlength];
for(int i=0;i< orig.length;i++){
copya[i]=orig[i];
}
for(int i=orig.length;i<newlength;i++){
copya[i]=0x0;
}
return copya;
}
}
目标C代码:
+(NSString*)doCipher:(NSString*)message key:(NSString*)key operation:(CCOperation)encryptOrDecrypt {
const void *messageData;
size_t messageBufferSize;
if (encryptOrDecrypt == kCCDecrypt){
NSData *messageEncryptData= [NSData dataFromBase64String:message];
messageBufferSize= [messageEncryptData length];
messageData= [messageEncryptData bytes];
}
else{
messageBufferSize= message.length;
messageData = [[[message dataUsingEncoding: NSUTF8StringEncoding]mutableCopy] bytes];
}
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
bufferPtrSize = (messageBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
uint8_t iv[kCCBlockSize3DES];
memset((void *) iv, 0x0, (size_t) sizeof(iv));
NSMutableData *keyData = [[key dataUsingEncoding:NSUTF8StringEncoding]mutableCopy];
NSData *keyEncodedMD5 = [NSData MD5Digest:keyData];
NSMutableData *keyDataAux = [NSMutableData dataWithData:keyEncodedMD5];
NSRange rangeToModify = NSMakeRange([keyEncodedMD5 length], kCCKeySize3DES - [keyEncodedMD5 length]);
[keyDataAux setLength: kCCKeySize3DES];
[keyDataAux replaceBytesInRange:rangeToModify withBytes:[keyEncodedMD5 bytes]];
ccStatus = CCCrypt(encryptOrDecrypt, // CCoperation op
kCCAlgorithm3DES, // CCAlgorithm alg
kCCOptionPKCS7Padding, // CCOptions
[keyDataAux bytes], // const void *key
kCCKeySize3DES, // 3DES key size length 24 bytes
iv, //const void *iv,
messageData, // const void *dataIn
messageBufferSize, // size_t dataInLength
(void *)bufferPtr, // void *dataOut
bufferPtrSize, // size_t dataOutAvailable
&movedBytes); // size_t *dataOutMoved
if (ccStatus == kCCParamError) return @"PARAM ERROR";
else if (ccStatus == kCCBufferTooSmall) return @"BUFFER TOO SMALL";
else if (ccStatus == kCCMemoryFailure) return @"MEMORY FAILURE";
else if (ccStatus == kCCAlignmentError) return @"ALIGNMENT";
else if (ccStatus == kCCDecodeError) return @"DECODE ERROR";
else if (ccStatus == kCCUnimplemented) return @"UNIMPLEMENTED";
NSString *result;
if (encryptOrDecrypt == kCCDecrypt){
result = [[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes] encoding:NSUTF8StringEncoding] ;
}
else{
NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
result= [myData base64EncodedString];
}
return result;
}
答案 1 :(得分:0)
Objective-C代码:
+ (NSString*) doCipher:(NSString*)plainText operation:(CCOperation)encryptOrDecrypt
{
const void *vplainText;
size_t plainTextBufferSize;
if (encryptOrDecrypt == kCCDecrypt)
{
NSData *EncryptData = [[NSData alloc] initWithBase64EncodedString:plainText];
plainTextBufferSize = [EncryptData length];
vplainText = [EncryptData bytes];
}
else
{
plainTextBufferSize = [plainText length];
vplainText = (const void *) [plainText UTF8String];
}
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
uint8_t iv[kCCBlockSize3DES];
memset((void *) iv, 0x00, (size_t) sizeof(iv));
bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
NSData *testData = [self md5DataFromString:SECRET_KEY];
const char *constSource = [testData bytes];
unsigned char source[24];
memcpy(source, constSource, sizeof (source));
for (int j = 0, k = 16; j < 8;) {
source[k++] = source[j++];
}
ccStatus = CCCrypt(encryptOrDecrypt,
kCCAlgorithm3DES,
kCCOptionPKCS7Padding,
source,
kCCKeySize3DES,
iv,
vplainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes);
if (ccStatus == kCCSuccess) NSLog(@"SUCCESS");
else if (ccStatus == kCCParamError) return @"PARAM ERROR";
else if (ccStatus == kCCBufferTooSmall) return @"BUFFER TOO SMALL";
else if (ccStatus == kCCMemoryFailure) return @"MEMORY FAILURE";
else if (ccStatus == kCCAlignmentError) return @"ALIGNMENT";
else if (ccStatus == kCCDecodeError) return @"DECODE ERROR";
else if (ccStatus == kCCUnimplemented) return @"UNIMPLEMENTED";
NSString *result;
if (encryptOrDecrypt == kCCDecrypt)
{
result = [[NSString alloc] initWithData: [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes] encoding:NSUTF8StringEncoding];
}
else
{
NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
result = [myData base64Encoding];
}
return result;
}
+ (NSData *)md5DataFromString:(NSString *)input
{
const char *cStr = [input UTF8String];
unsigned char digest[16];
CC_MD5( cStr, strlen(cStr), digest ); // This is the md5 call
return [NSData dataWithBytes:digest length:CC_MD5_DIGEST_LENGTH];
}