Implementierung der AES-Verschlüsselung und -Entschlüsselung für die iOS JAVA-Interkommunikation

Hintergrund: Aus geschäftlichen Gründen müssen Links auf mobilen Seiten verschlüsselt und entschlüsselt werden. Nachdem die Back-End-Verschlüsselung abgeschlossen ist, erfolgt die Entschlüsselung im Front-End (iOS, Android). Android hat mit dem Schlüssel erfolgreich entschlüsselt, und das in zehn Minuten (das ist nicht einfach~). iOS nimmt den Schlüssel zum Entschlüsseln, entweder führt die Entschlüsselung zu verstümmelten Zeichen oder zu Null, und sie wurde nach einem halben Tag nicht durchgeführt (eigentlich unentschieden, Q).

Nachfolgend finden Sie den Code, der durch unermüdliche Bemühungen erfolgreich entschlüsselt wurde. iOS, Android und JAVA können sich gegenseitig ver- und entschlüsseln und bei Bedarf direkt kopieren und verwenden.

1. iOS-Verschlüsselung und -Entschlüsselung

AESUtil.h

#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonCryptor.h>
NS_ASSUME_NONNULL_BEGIN

@interface AESUtil : NSObject

/**
 * AES加密
 */
+ (NSString *)encryptAES:(NSString *)content;
 
/**
 * AES解密
 */
+ (NSString *)decryptAES:(NSString *)content;


@end

NS_ASSUME_NONNULL_END

2、AESUtil.m

#import "AESUtil.h"

//key
static NSString *const PSW_AES_KEY = @"--32位字母数字组成的字符串--";
//偏移量
NSString *const kInitVector = @"--16位字母数字组成的字符串--";
//密钥长度
size_t const kKeySize = kCCKeySizeAES256;//kCCKeySizeAES128
@implementation AESUtil

+ (NSString *)encryptAES:(NSString *)content {
    NSData *contentData = [content dataUsingEncoding:NSUTF8StringEncoding];
    NSUInteger dataLength = contentData.length;
    // 为结束符'\\0' +1
    char keyPtr[kKeySize + 1];
    memset(keyPtr, 0, sizeof(keyPtr));
    [PSW_AES_KEY getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    // 密文长度 <= 明文长度 + BlockSize
    size_t encryptSize = dataLength + kCCBlockSizeAES128;
    void *encryptedBytes = malloc(encryptSize);
    size_t actualOutSize = 0;
    NSData *initVector = [kInitVector dataUsingEncoding:NSUTF8StringEncoding];
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          kCCAlgorithmAES,
                                          kCCOptionPKCS7Padding,  // 系统默认使用 CBC,使用 PKCS7Padding
                                          keyPtr,
                                          kKeySize,
                                          initVector.bytes,
                                          contentData.bytes,
                                          dataLength,
                                          encryptedBytes,
                                          encryptSize,
                                          &actualOutSize);
    if (cryptStatus == kCCSuccess) {
        // 对加密后的数据 base64 编码
        return [[NSData dataWithBytesNoCopy:encryptedBytes length:actualOutSize] base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
    }
    free(encryptedBytes);
    return nil;
}

+ (NSString *)decryptAES:(NSString *)content{
    NSData *contentData = [[NSData alloc] initWithBase64EncodedString:content options:NSDataBase64DecodingIgnoreUnknownCharacters];
    NSUInteger dataLength = contentData.length;
    char keyPtr[kKeySize + 1];
    memset(keyPtr, 0, sizeof(keyPtr));
    [PSW_AES_KEY getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    size_t decryptSize = dataLength + kCCBlockSizeAES128;
    void *decryptedBytes = malloc(decryptSize);
    size_t actualOutSize = 0;
    NSData *initVector = [kInitVector dataUsingEncoding:NSUTF8StringEncoding];
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                          kCCAlgorithmAES,
                                          kCCOptionPKCS7Padding,
                                          keyPtr,
                                          kKeySize,
                                          initVector.bytes,
                                          contentData.bytes,
                                          dataLength,
                                          decryptedBytes,
                                          decryptSize,
                                          &actualOutSize);
    if (cryptStatus == kCCSuccess) {
        return [[NSString alloc] initWithData:[NSData dataWithBytesNoCopy:decryptedBytes length:actualOutSize] encoding:NSUTF8StringEncoding];
    }
    free(decryptedBytes);
    return nil;
}

@end

Hinweis: Die entschlüsselte Zeichenfolge enthält das unsichtbare Zeichen „\0“, das wie folgt durch „“ ersetzt werden muss

NSString *result = [decryptContent stringByReplacingOccurrencesOfString:@"\0" withString:@""];

Zweitens: Android, JAVA-Verschlüsselung und -Entschlüsselung

public class AESUtil {
    private static final String AES = "AES";
    private static final String Mode = "AES/CBC/PKCS5Padding";

    private static Cipher cipherEncrypt;
    private static Cipher cipherDecrypt;
    /**
      * AES加密
      */
    public static String encrypt(String aPlaintext, String aKey) {
        String originalString = "";
        try {
            String tmpIv = aKey.substring(16, 32);
            SecretKeySpec keyspec = new SecretKeySpec(aKey.getBytes(), AES);
            IvParameterSpec ivspec = new IvParameterSpec(tmpIv.getBytes());
            cipherEncrypt = Cipher.getInstance(Mode);
            cipherEncrypt.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);

            byte[] encrypted = null;
            int blockSize = cipherEncrypt.getBlockSize();
            byte[] dataBytes = aPlaintext.getBytes();
            int plaintextLength = dataBytes.length;
            if (plaintextLength % blockSize != 0) {
                plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
            }
            byte[] plaintext = new byte[plaintextLength];
            System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);

            try {
                encrypted = cipherEncrypt.doFinal(plaintext);
            } catch (IllegalBlockSizeException e) {
                e.printStackTrace();
            } catch (BadPaddingException e) {
                e.printStackTrace();
            }
            if (encrypted == null) {
                LogUtils.e("算法加密错误!返回无结果");
                return null;
            }
            originalString = Base64.encodeToString(encrypted, Base64.DEFAULT);
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        }

        return originalString.trim();
    }
    /**
      * AES解密
      */
    public static String decrypt(String aCiphertext, String aKey) {
        String originalString = "";
        try {
            String tmpIv = aKey.substring(16, 32);
            SecretKeySpec keyspec = new SecretKeySpec(aKey.getBytes(), AES);
            IvParameterSpec ivspec = new IvParameterSpec(tmpIv.getBytes());
            cipherDecrypt = Cipher.getInstance(Mode);
            cipherDecrypt.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
            byte[] sourcebyte = Base64.decode(aCiphertext, Base64.DEFAULT);
            byte[] original = null;
            original = cipherDecrypt.doFinal(sourcebyte);
            try {
                originalString = new String(original, "utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            LogUtils.e("设置算法错误!");
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            LogUtils.e("解密算法密钥设置错误!");
            LogUtils.e("解密算法密钥长度不够,过长!");
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            LogUtils.e("算法解密过程错误!");
            LogUtils.e("块大小设置错误!密文长度不够或太长!");
            e.printStackTrace();
        } catch (BadPaddingException e) {
            LogUtils.e("解密算法解密过程错误!");
            LogUtils.e("解密填充方式错误!");
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        }
        return originalString.trim();
    }
}

Wenn der Artikel für Sie hilfreich ist, vergessen Sie nicht, ihm einen Daumen nach oben zu geben~

Guess you like

Origin blog.csdn.net/c_furong/article/details/127265137