使用任何东西在Ruby中的Objective-C / Decrypt中加密

我们使用此代码在iPhone上的Objective-C中进行加密:

- (NSMutableData*) EncryptAES: (NSString *) key { char keyPtr[kCCKeySizeAES128+1]; bzero( keyPtr, sizeof(keyPtr) ); [key getCString: keyPtr maxLength: sizeof(keyPtr) encoding: NSUTF8StringEncoding]; size_t numBytesEncrypted = 0; NSUInteger dataLength = [self length]; size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); NSMutableData *output = [[NSData alloc] init]; CCCryptorStatus result = CCCrypt( kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, keyPtr, kCCKeySizeAES128, NULL, [self mutableBytes], [self length], buffer, bufferSize, &numBytesEncrypted ); output = [NSMutableData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; if( result == kCCSuccess ) { return output; } return NULL; } 

并尝试使用Ruby中的OpenSSL解密它,如下所示:

 aes = OpenSSL::Cipher::Cipher.new('AES-128-CBC') aes.decrypt aes.padding = 1 aes.iv = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0].pack('c*') aes.key = key result = aes.update(d) + aes.final 

我愿意使用任何rubygem。 我可以控制双方,但我无法使用EzCrypto,openssl或crypt。

有谁知道如何让这些一起工作?

您的代码泄漏了第一个输出分配。

除此之外它看起来很好。

这是一个完整的端到端实现,使用用户密码的SHA256哈希(在本例中为’Salamander’)和base64’输出。 在源中有一个PHP测试实现,它重建密钥然后在给出最终输出之前修剪PKCS7填充。 随后是Ruby中的解密器,OpenSSL :: Cipher自动发生PKCS7填充删除。

干得好:

 // Crypto categories for iOS #import  #import  @interface NSData( Crypto ) - (NSData *) aesEncryptedDataWithKey:(NSData *) key; - (NSString *) base64Encoding; @end @interface NSString( Crypto ) - (NSData *) sha256; @end // -------- @implementation NSData( Crypto ) - (NSData *) aesEncryptedDataWithKey:(NSData *) key { unsigned char *buffer = nil; size_t bufferSize; CCCryptorStatus err; NSUInteger i, keyLength, plainTextLength; // make sure there's data to encrypt err = ( plainTextLength = [self length] ) == 0; // pass the user's passphrase through SHA256 to obtain 32 bytes // of key data. Use all 32 bytes for an AES256 key or just the // first 16 for AES128. if ( ! err ) { switch ( ( keyLength = [key length] ) ) { case kCCKeySizeAES128: case kCCKeySizeAES256: break; // invalid key size default: err = 1; break; } } // create an output buffer with room for pad bytes if ( ! err ) { bufferSize = kCCBlockSizeAES128 + plainTextLength + kCCBlockSizeAES128; // iv + cipher + padding err = ! ( buffer = (unsigned char *) malloc( bufferSize ) ); } // encrypt the data if ( ! err ) { srandomdev(); // generate a random iv and prepend it to the output buffer. the // decryptor needs to be aware of this. for ( i = 0; i < kCCBlockSizeAES128; ++i ) buffer[ i ] = random() & 0xff; err = CCCrypt( kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, [key bytes], keyLength, buffer, [self bytes], plainTextLength, buffer + kCCBlockSizeAES128, bufferSize - kCCBlockSizeAES128, &bufferSize ); } if ( err ) { if ( buffer ) free( buffer ); return nil; } // dataWithBytesNoCopy takes ownership of buffer and will free() it // when the NSData object that owns it is released. return [NSData dataWithBytesNoCopy: buffer length: bufferSize + kCCBlockSizeAES128]; } - (NSString *) base64Encoding { char *encoded, *r; const char eTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; unsigned i, l, n, t; UInt8 *p, pad = '='; NSString *result; p = (UInt8 *) [self bytes]; if ( ! p || ( l = [self length] ) == 0 ) return @""; r = encoded = malloc( 4 * ( ( n = l / 3 ) + ( l % 3 ? 1 : 0 ) ) + 1 ); if ( ! encoded ) return nil; for ( i = 0; i < n; ++i ) { t = *p++ << 16; t |= *p++ << 8; t |= *p++; *r++ = eTable[ t >> 18 ]; *r++ = eTable[ t >> 12 & 0x3f ]; *r++ = eTable[ t >> 6 & 0x3f ]; *r++ = eTable[ t & 0x3f ]; } if ( ( i = n * 3 ) < l ) { t = *p++ << 16; *r++ = eTable[ t >> 18 ]; if ( ++i < l ) { t |= *p++ << 8; *r++ = eTable[ t >> 12 & 0x3f ]; *r++ = eTable[ t >> 6 & 0x3f ]; } else { *r++ = eTable[ t >> 12 & 0x3f ]; *r++ = pad; } *r++ = pad; } *r = 0; result = [NSString stringWithUTF8String: encoded]; free( encoded ); return result; } @end @implementation NSString( Crypto ) - (NSData *) sha256 { unsigned char *buffer; if ( ! ( buffer = (unsigned char *) malloc( CC_SHA256_DIGEST_LENGTH ) ) ) return nil; CC_SHA256( [self UTF8String], [self lengthOfBytesUsingEncoding: NSUTF8StringEncoding], buffer ); return [NSData dataWithBytesNoCopy: buffer length: CC_SHA256_DIGEST_LENGTH]; } @end // ----------------- @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSData *plain = [@"This is a test of the emergency broadcast system." dataUsingEncoding: NSUTF8StringEncoding]; NSData *key = [NSData dataWithBytes: [[@"Salamander" sha256] bytes] length: kCCKeySizeAES128]; NSData *cipher = [plain aesEncryptedDataWithKey: key]; NSString *base64 = [cipher base64Encoding]; NSLog( @"cipher: %@", base64 ); // stuff the base64'ed cipher into decrypt.php: // http://localhost/~par/decrypt.php?cipher= /*  */ return YES; } @end 

在Ruby中解密上面的输出:

 require 'base64' require 'openssl' def decrypt( cipherBase64 ) cipher = Base64.decode64( cipherBase64 ) aes = OpenSSL::Cipher::Cipher.new( "aes-128-cbc" ).decrypt aes.iv = cipher.slice( 0, 16 ) # don't slice the SHA256 output for AES256 aes.key = ( Digest::SHA256.digest( 'Salamander' ) ).slice( 0, 16 ) cipher = cipher.slice( 16..-1 ) return aes.update( cipher ) + aes.final end text = '3o4ARWOxwmLEPgq3SJ3A2ws7sUSxMvWSKbbs+oABsOcywk+9qPBoDjhLAfAW/n28pbnsT2w5QMSye6pz3Lz8xmg5BYL8HdfKwbS9EpTbaUc=' print decrypt( text ) + "\n" 

我没有做你正在做的事情,至少不完全是这样,但以下值得一试。

 require 'crypt/rijndael' require 'Base64' rijndael = Crypt::Rijndael.new("samepassword") decryptedBlock = rijndael.decrypt_block(Base64.decode64("encrypted-b64-encoded-data")) 

我认为Jonas在使用Rijndael方面可能是正确的。 我记得和Crypt一起工作,需要指定密码。

您也可以使用以下库提供内置的AES-256-CBC密码和Base64编码,您可以在两个平台上快速使用这些编码:

ruby

https://github.com/Gurpartap/aescrypt

以下是使用AESCrypt Ruby gem的方法:

 message = "top secret message" password = "p4ssw0rd" # Encrypting encrypted_data = AESCrypt.encrypt(message, password) # Decrypting message = AESCrypt.decrypt(encrypted_data, password) 

Objective-C的

https://github.com/Gurpartap/AESCrypt-ObjC

以下是使用AESCrypt Objective-C类的方法:

 NSString *message = @"top secret message"; NSString *password = @"p4ssw0rd"; // Encrypting NSString *encryptedData = [AESCrypt encrypt:message password:password]; // Decrypting NSString *message = [AESCrypt decrypt:encryptedData password:password]; 

希望能帮助到你!