填充算法,mac与java的区别
(加密是由算法/模式/填充组成的,算法是DES,AES等, 模式是EBC,CBC等,这里主要看填充)
mac支持:
NoPadding
PKCS7Padding
而java支持:
NoPadding
ISO10126Padding
OAEPPadding, OAEPWith<digest>And<mgf>Padding
PKCS1Padding
PKCS5Padding
SSL3Padding
NoPadding就是不填充,相当于自定义填充,显然太麻烦。
除此之外,就没有相同的了。
那么如何让iphone加密的数据,由服务器的java解开呢?
mac的PKCS7Padding在java中没有,那麻烦了,试了一下,可以如下解决。
1.都用NoPadding,太痛苦,放弃
2.java下载扩展包,让java支持PKCS7Padding,可以考虑,但要服务器加java的扩展包
3.别使用AES算法了,使用DES或3DES等,因为它们的加密数据包单位长度是8字节,在8字节的情况下PKCS7Padding 等价与 PKCS5Padding。
附加一些代码
iphone的DES/EBC/PKCS7Padding加密并且加md5
- (NSData *)DESMD5EncryptWithKey:(NSString *)key {
char keyPtr[kCCKeySizeDES + 1]; // room for terminator (unused)
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
// fetch key data
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSLog(@"key:%@", key);
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeDES;
void* buffer = malloc(bufferSize + CC_MD5_DIGEST_LENGTH);
unsigned char md5Result[CC_MD5_DIGEST_LENGTH];
CC_MD5( [self bytes], [self length], md5Result );
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionPKCS7Padding|kCCOptionECBMode,
keyPtr, kCCKeySizeDES,
NULL /* initialization vector (optional) */,
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted);
if (cryptStatus == kCCSuccess && numBytesEncrypted<=bufferSize )
{
memcpy( buffer+numBytesEncrypted, md5Result, CC_MD5_DIGEST_LENGTH);
return [NSMutableData dataWithBytesNoCopy:buffer length:(numBytesEncrypted + CC_MD5_DIGEST_LENGTH) ];
}
free(buffer);
return nil;
}
java的DES/EBC/PKCS5Padding 加密解密
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class MainClass {
public static void main(String[] args) throws Exception {
// Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
byte[] input = "123".getBytes();
byte[] keyBytes = new byte[] { '0', '1', '2', '3', '4', '5', '6', '7' };
SecretKeySpec key = new SecretKeySpec(keyBytes, "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
//Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
System.out.println(new String(input));
// encryption pass
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
ctLength += cipher.doFinal(cipherText, ctLength);
for ( int i=0; i<ctLength; i++ )
System.out.println(cipherText[i]);
System.out.println("========");
// decryption pass
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] plainText = new byte[cipher.getOutputSize(ctLength)];
int ptLength = cipher.update(cipherText, 0, ctLength, plainText, 0);
ptLength += cipher.doFinal(plainText, ptLength);
System.out.println(new String(plainText));
System.out.println(ptLength);
}
}
mac支持:
NoPadding
PKCS7Padding
而java支持:
NoPadding
ISO10126Padding
OAEPPadding, OAEPWith<digest>And<mgf>Padding
PKCS1Padding
PKCS5Padding
SSL3Padding
NoPadding就是不填充,相当于自定义填充,显然太麻烦。
除此之外,就没有相同的了。
那么如何让iphone加密的数据,由服务器的java解开呢?
mac的PKCS7Padding在java中没有,那麻烦了,试了一下,可以如下解决。
1.都用NoPadding,太痛苦,放弃
2.java下载扩展包,让java支持PKCS7Padding,可以考虑,但要服务器加java的扩展包
3.别使用AES算法了,使用DES或3DES等,因为它们的加密数据包单位长度是8字节,在8字节的情况下PKCS7Padding 等价与 PKCS5Padding。
附加一些代码
iphone的DES/EBC/PKCS7Padding加密并且加md5
- (NSData *)DESMD5EncryptWithKey:(NSString *)key {
char keyPtr[kCCKeySizeDES + 1]; // room for terminator (unused)
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
// fetch key data
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSLog(@"key:%@", key);
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCBlockSizeDES;
void* buffer = malloc(bufferSize + CC_MD5_DIGEST_LENGTH);
unsigned char md5Result[CC_MD5_DIGEST_LENGTH];
CC_MD5( [self bytes], [self length], md5Result );
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionPKCS7Padding|kCCOptionECBMode,
keyPtr, kCCKeySizeDES,
NULL /* initialization vector (optional) */,
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted);
if (cryptStatus == kCCSuccess && numBytesEncrypted<=bufferSize )
{
memcpy( buffer+numBytesEncrypted, md5Result, CC_MD5_DIGEST_LENGTH);
return [NSMutableData dataWithBytesNoCopy:buffer length:(numBytesEncrypted + CC_MD5_DIGEST_LENGTH) ];
}
free(buffer);
return nil;
}
java的DES/EBC/PKCS5Padding 加密解密
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class MainClass {
public static void main(String[] args) throws Exception {
// Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
byte[] input = "123".getBytes();
byte[] keyBytes = new byte[] { '0', '1', '2', '3', '4', '5', '6', '7' };
SecretKeySpec key = new SecretKeySpec(keyBytes, "DES");
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
//Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
System.out.println(new String(input));
// encryption pass
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
ctLength += cipher.doFinal(cipherText, ctLength);
for ( int i=0; i<ctLength; i++ )
System.out.println(cipherText[i]);
System.out.println("========");
// decryption pass
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] plainText = new byte[cipher.getOutputSize(ctLength)];
int ptLength = cipher.update(cipherText, 0, ctLength, plainText, 0);
ptLength += cipher.doFinal(plainText, ptLength);
System.out.println(new String(plainText));
System.out.println(ptLength);
}
}