Skip to content

Instantly share code, notes, and snippets.

@ytyng
Last active August 29, 2015 14:16
Show Gist options
  • Save ytyng/e7f48902950347894c0b to your computer and use it in GitHub Desktop.
Save ytyng/e7f48902950347894c0b to your computer and use it in GitHub Desktop.
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonCryptor.h>
@interface AES128ECBCipher : NSObject
- (AES128ECBCipher *)initWithKey:(NSString *)key;
#pragma mark - encryption
- (NSData *)encryptWithString:(NSString *)string;
- (NSString *)encryptToBase64WithString:(NSString *)string;
- (NSString *)encryptToBase64WithData:(NSData *)data;
- (NSData *)encryptWithData:(NSData *)data;
#pragma mark - decryption
- (NSString *)decryptToStringWithBase64:(NSString *)base64string;
- (NSData *)decryptWithBase64:(NSString *)base64string;
- (NSString *)decryptToStringWithData:(NSData *)data;
- (NSData *)decryptWithData:(NSData *)data;
@end
#import "AES128ECBCipher.h"
@interface AES128ECBCipher ()
@property(nonatomic) NSString *key;
@end
typedef enum {
AESTypeEncrypt,
AESTypeDecrypt,
} kAESType;
@implementation AES128ECBCipher {
}
- (AES128ECBCipher *)initWithKey:(NSString *)key {
self = [super init];
if (self) {
self.key = key;
}
return self;
}
#pragma mark - encryption
- (NSData *)encryptWithString:(NSString *)string {
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
return [self AES128ECBWithData:data AESType:AESTypeEncrypt];
}
- (NSString *)encryptToBase64WithString:(NSString *)string {
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
return [self encryptToBase64WithData:data];
}
- (NSString *)encryptToBase64WithData:(NSData *)data {
NSData *encrypted = [self AES128ECBWithData:data AESType:AESTypeEncrypt];
return [encrypted base64EncodedStringWithOptions:0];
}
- (NSData *)encryptWithData:(NSData *)data {
return [self AES128ECBWithData:data AESType:AESTypeEncrypt];
}
#pragma mark - decryption
- (NSString *)decryptToStringWithBase64:(NSString *)base64string {
NSData *data = [[NSData alloc] initWithBase64EncodedString:base64string options:0];
return [self decryptToStringWithData:data];
}
- (NSData *)decryptWithBase64:(NSString *)base64string {
NSData *data = [[NSData alloc] initWithBase64EncodedString:base64string options:0];
return [self decryptWithData:data];
}
- (NSString *)decryptToStringWithData:(NSData *)data {
NSData *decrypted = [self decryptWithData:data];
return [[NSString alloc] initWithData:decrypted encoding:NSUTF8StringEncoding];
}
- (NSData *)decryptWithData:(NSData *)data {
return [self AES128ECBWithData:data AESType:AESTypeDecrypt];
}
#pragma mark - core
- (NSData *)AES128ECBWithData:(NSData *)data AESType:(kAESType)aesType {
char keyPtr[kCCKeySizeAES128 + 1];
bzero(keyPtr, sizeof(keyPtr));
[self.key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
CCOperation type;
if (aesType == AESTypeEncrypt) {
type = kCCEncrypt;
} else {
type = kCCDecrypt;
}
size_t numBytes = 0;
CCCryptorStatus cryptStatus = CCCrypt(type, kCCAlgorithmAES128,
kCCOptionECBMode | kCCOptionPKCS7Padding,
keyPtr, kCCBlockSizeAES128,
NULL,
[data bytes], dataLength,
buffer, bufferSize,
&numBytes);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytes];
}
free(buffer);
return nil;
}
@end
"""
python3
AES128 PKCS7 暗号
Initial Vector なし
キーはゼロパディング
"""
import base64
from Crypto.Cipher import AES
class AES128ECBCipher(object):
"""
>>> key = "bbbbb"
>>> cipher = AES128ECBCipher(key)
>>> encrypted = cipher.encrypt_by_str_to_b64s('aaaaa')
>>> print(encrypted)
RP46xqG5/dG1HeVUX9kvIg==
>>> print(cipher.decrypt_by_b64s_to_str(encrypted))
aaaaa
"""
text_encoding = 'utf-8'
pad_block_size = 16
key_size = 16
class AES128CipherError(Exception):
pass
def __init__(self, key):
self.key = self.pad_key(key)
def pad_key(self, key):
return key + ('\0' * (
self.key_size - len(key) % self.key_size))
def encrypt_by_str_to_b64s(self, plain_str):
"""
:param plain_str:
:rtype: str
"""
return self.encrypt_to_b64s(
bytes(plain_str, encoding=self.text_encoding))
def encrypt_to_b64s(self, plain_data):
"""
:type plain_data: bytes
:rtype: str
"""
return str(base64.b64encode(self.encrypt(plain_data)),
encoding=self.text_encoding)
def encrypt_by_str(self, plain_str):
"""
:param plain_str:
:rtype: bytes
"""
return self.encrypt(
bytes(plain_str, encoding=self.text_encoding))
def encrypt(self, plain_data):
"""
:type plain_data: bytes
:rtype: bytes
"""
if not isinstance(plain_data, bytes):
raise self.AES128CipherError('Input type must be bytes')
padded = self.pad_pkcs7(plain_data)
cipher = AES.new(self.key, AES.MODE_ECB)
return cipher.encrypt(padded)
def decrypt_by_b64s_to_str(self, encrypted_str):
"""
:type encrypted_str: str
:rtype: str
"""
return str(self.decrypt_by_b64s(encrypted_str),
encoding=self.text_encoding)
def decrypt_by_b64s(self, encrypted_str):
"""
:type encrypted_str: str
:rtype: bytes
"""
return self.decrypt(base64.b64decode(
bytes(encrypted_str, encoding=self.text_encoding)))
def decrypt(self, encrypted_data):
"""
:type encrypted_data: bytes
:rtype: bytes
"""
cipher = AES.new(self.key, AES.MODE_ECB)
return self.unpad_pkcs7(cipher.decrypt(encrypted_data))
def pad_pkcs7(self, bytestring):
"""
Pad an input bytestring according to PKCS#7
"""
l = len(bytestring)
val = self.pad_block_size - (l % self.pad_block_size)
return bytestring + bytearray([val] * val)
def unpad_pkcs7(self, bytestring):
"""
Remove the PKCS#7 padding from a text bytestring.
"""
val = bytestring[-1]
if val > self.pad_block_size:
raise ValueError('Input is not padded or padding is corrupt')
l = len(bytestring) - val
return bytestring[:l]
@ytyng
Copy link
Author

ytyng commented Feb 28, 2015

Python3 と Objective-C で互換動作する暗号化
・AES 128ビット
・ECBモード
・PKCS7パディング
・キーは16桁になるようヌルパディング
ネットから情報あつめて作った

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment