【发布时间】:2018-07-02 10:20:22
【问题描述】:
我在 iOS 中遇到了 PBEWithMD5AndDES 加密问题。我已经使用https://gist.github.com/788840/24bc73ecd0ac3134cbd242892c74a06ac561d37b 对我的字符串进行了加密和解密。
问题是我得到不同的加密值,具体取决于我的方法所在的类。例如,我将所有加密方法移动到一个帮助程序类中并运行它。我注意到我得到了不同的加密值。
我现在在不同的类中有相同方法的两个相同版本,并且我正在并排运行它们。他们得到不同的加密值,一个不能解密其他的。我对此感到有些困惑。
这是进行加密/解密的辅助类。
@implementation CryptoHelper
#pragma mark -
#pragma mark Init Methods
- (id)init
{
if(self = [super init])
{
}
return self;
}
#pragma mark -
#pragma mark String Specific Methods
/**
* Encrypts a string for social blast service.
*
* @param plainString The string to encrypt;
*
* @return NSString The encrypted string.
*/
- (NSString *)encryptString: (NSString *) plainString{
// Convert string to data and encrypt
NSData *data = [self encryptPBEWithMD5AndDESData:[plainString dataUsingEncoding:NSUTF8StringEncoding] password:@"1111"];
// Get encrypted string from data
return [data base64EncodingWithLineLength:1024];
}
/**
* Descrypts a string from social blast service.
*
* @param plainString The string to decrypt;
*
* @return NSString The decrypted string.
*/
- (NSString *)decryptString: (NSString *) encryptedString{
// decrypt the data
NSData * data = [self decryptPBEWithMD5AndDESData:[NSData dataWithBase64EncodedString:encryptedString] password:@"1111"];
// extract and return string
return [NSString stringWithUTF8String:[data bytes]];
}
#pragma mark -
#pragma mark Crypto Methods
- (NSData *)encryptPBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password {
return [self encodePBEWithMD5AndDESData:inData password:password direction:1];
}
- (NSData *)decryptPBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password {
return [self encodePBEWithMD5AndDESData:inData password:password direction:0];
}
- (NSData *)encodePBEWithMD5AndDESData:(NSData *)inData password:(NSString *)password direction:(int)direction
{
NSLog(@"helper data = %@", inData);
static const char gSalt[] =
{
(unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA,
(unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA, (unsigned char)0xAA
};
unsigned char *salt = (unsigned char *)gSalt;
int saltLen = strlen(gSalt);
int iterations = 15;
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);*/
const EVP_CIPHER *cipher = EVP_des_cbc();
// Need to set with iv
X509_ALGOR *algorithm = PKCS5_pbe2_set_iv(cipher, iterations,
salt, saltLen, salt, NID_hmacWithMD5);
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:%s\n\tfunction:%s\n\treason:%s\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]; //(NSData *)encr_buf;
//NSLog(@"encryption result: %@\n", [encryptedData base64EncodingWithLineLength:1024]);
EVP_cleanup();
return encryptedData;
}
}
EVP_cleanup();
return nil;
}
@end
我正在尝试复制此 java 函数的结果。我有同样的盐。
public DesEncrypter(String passPhrase) {
try {
// Create the key
KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt, iterationCount);
SecretKey key = SecretKeyFactory.getInstance(
"PBEWithMD5AndDES").generateSecret(keySpec);
ecipher = Cipher.getInstance(key.getAlgorithm());
dcipher = Cipher.getInstance(key.getAlgorithm());
// Prepare the parameter to the ciphers
AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
// Create the ciphers
ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
} catch (java.security.InvalidAlgorithmParameterException e) {
} catch (java.security.spec.InvalidKeySpecException e) {
} catch (javax.crypto.NoSuchPaddingException e) {
} catch (java.security.NoSuchAlgorithmException e) {
} catch (java.security.InvalidKeyException e) {
}
}
【问题讨论】:
标签: iphone objective-c ios encryption openssl