DES for iOS and Java

The message only tell us the reason, but be care if the string contains some chinese words, if u don't convert the string into NSData, you may get a wrong lenth of the string.

 

(加密是由算法/模式/填充组成的,算法是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);
  }
}

你可能感兴趣的:(java)