ios版 ,公钥私钥一键加密解密
@interface RSA : NSObject // return base64 encoded string + (NSString *)encryptString:(NSString *)str publicKey:(NSString *)pubKey; // return raw data + (NSData *)encryptData:(NSData *)data publicKey:(NSString *)pubKey; // return base64 encoded string // enc with private key NOT working YET! //+ (NSString *)encryptString:(NSString *)str privateKey:(NSString *)privKey; // return raw data //+ (NSData *)encryptData:(NSData *)data privateKey:(NSString *)privKey; // decrypt base64 encoded string, convert result to string(not base64 encoded) + (NSString *)decryptString:(NSString *)str publicKey:(NSString *)pubKey; + (NSData *)decryptData:(NSData *)data publicKey:(NSString *)pubKey; + (NSString *)decryptString:(NSString *)str privateKey:(NSString *)privKey; + (NSData *)decryptData:(NSData *)data privateKey:(NSString *)privKey; @end
/* @author: ideawu @link: https://github.com/ideawu/Objective-C-RSA */ #import "RSA.h" #import <Security/Security.h> @implementation RSA /* static NSString *base64_encode(NSString *str){ NSData* data = [str dataUsingEncoding:NSUTF8StringEncoding]; if(!data){ return nil; } return base64_encode_data(data); } */ static NSString *base64_encode_data(NSData *data){ data = [data base64EncodedDataWithOptions:0]; NSString *ret = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; return ret; } static NSData *base64_decode(NSString *str){ NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters]; return data; } + (NSData *)stripPublicKeyHeader:(NSData *)d_key{ // Skip ASN.1 public key header if (d_key == nil) return(nil); unsigned long len = [d_key length]; if (!len) return(nil); unsigned char *c_key = (unsigned char *)[d_key bytes]; unsigned int idx = 0; if (c_key[idx++] != 0x30) return(nil); if (c_key[idx] > 0x80) idx += c_key[idx] - 0x80 + 1; else idx++; // PKCS #1 rsaEncryption szOID_RSA_RSA static unsigned char seqiod[] = { 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00 }; if (memcmp(&c_key[idx], seqiod, 15)) return(nil); idx += 15; if (c_key[idx++] != 0x03) return(nil); if (c_key[idx] > 0x80) idx += c_key[idx] - 0x80 + 1; else idx++; if (c_key[idx++] != '\0') return(nil); // Now make a new NSData from this buffer return([NSData dataWithBytes:&c_key[idx] length:len - idx]); } //credit: http://hg.mozilla.org/services/fx-home/file/tip/Sources/NetworkAndStorage/CryptoUtils.m#l1036 + (NSData *)stripPrivateKeyHeader:(NSData *)d_key{ // Skip ASN.1 private key header if (d_key == nil) return(nil); unsigned long len = [d_key length]; if (!len) return(nil); unsigned char *c_key = (unsigned char *)[d_key bytes]; unsigned int idx = 22; //magic byte at offset 22 if (0x04 != c_key[idx++]) return nil; //calculate length of the key unsigned int c_len = c_key[idx++]; int det = c_len & 0x80; if (!det) { c_len = c_len & 0x7f; } else { int byteCount = c_len & 0x7f; if (byteCount + idx > len) { //rsa length field longer than buffer return nil; } unsigned int accum = 0; unsigned char *ptr = &c_key[idx]; idx += byteCount; while (byteCount) { accum = (accum << 8) + *ptr; ptr++; byteCount--; } c_len = accum; } // Now make a new NSData from this buffer return [d_key subdataWithRange:NSMakeRange(idx, c_len)]; } + (SecKeyRef)addPublicKey:(NSString *)key{ NSRange spos = [key rangeOfString:@"-----BEGIN PUBLIC KEY-----"]; NSRange epos = [key rangeOfString:@"-----END PUBLIC KEY-----"]; if(spos.location != NSNotFound && epos.location != NSNotFound){ NSUInteger s = spos.location + spos.length; NSUInteger e = epos.location; NSRange range = NSMakeRange(s, e-s); key = [key substringWithRange:range]; } key = [key stringByReplacingOccurrencesOfString:@"\r" withString:@""]; key = [key stringByReplacingOccurrencesOfString:@"\n" withString:@""]; key = [key stringByReplacingOccurrencesOfString:@"\t" withString:@""]; key = [key stringByReplacingOccurrencesOfString:@" " withString:@""]; // This will be base64 encoded, decode it. NSData *data = base64_decode(key); data = [RSA stripPublicKeyHeader:data]; if(!data){ return nil; } //a tag to read/write keychain storage NSString *tag = @"RSAUtil_PubKey"; NSData *d_tag = [NSData dataWithBytes:[tag UTF8String] length:[tag length]]; // Delete any old lingering key with the same tag NSMutableDictionary *publicKey = [[NSMutableDictionary alloc] init]; [publicKey setObject:(__bridge id) kSecClassKey forKey:(__bridge id)kSecClass]; [publicKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType]; [publicKey setObject:d_tag forKey:(__bridge id)kSecAttrApplicationTag]; SecItemDelete((__bridge CFDictionaryRef)publicKey); // Add persistent version of the key to system keychain [publicKey setObject:data forKey:(__bridge id)kSecValueData]; [publicKey setObject:(__bridge id) kSecAttrKeyClassPublic forKey:(__bridge id) kSecAttrKeyClass]; [publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id) kSecReturnPersistentRef]; CFTypeRef persistKey = nil; OSStatus status = SecItemAdd((__bridge CFDictionaryRef)publicKey, &persistKey); if (persistKey != nil){ CFRelease(persistKey); } if ((status != noErr) && (status != errSecDuplicateItem)) { return nil; } [publicKey removeObjectForKey:(__bridge id)kSecValueData]; [publicKey removeObjectForKey:(__bridge id)kSecReturnPersistentRef]; [publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef]; [publicKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType]; // Now fetch the SecKeyRef version of the key SecKeyRef keyRef = nil; status = SecItemCopyMatching((__bridge CFDictionaryRef)publicKey, (CFTypeRef *)&keyRef); if(status != noErr){ return nil; } return keyRef; } + (SecKeyRef)addPrivateKey:(NSString *)key{ NSRange spos = [key rangeOfString:@"-----BEGIN RSA PRIVATE KEY-----"]; NSRange epos = [key rangeOfString:@"-----END RSA PRIVATE KEY-----"]; if(spos.location != NSNotFound && epos.location != NSNotFound){ NSUInteger s = spos.location + spos.length; NSUInteger e = epos.location; NSRange range = NSMakeRange(s, e-s); key = [key substringWithRange:range]; } key = [key stringByReplacingOccurrencesOfString:@"\r" withString:@""]; key = [key stringByReplacingOccurrencesOfString:@"\n" withString:@""]; key = [key stringByReplacingOccurrencesOfString:@"\t" withString:@""]; key = [key stringByReplacingOccurrencesOfString:@" " withString:@""]; // This will be base64 encoded, decode it. NSData *data = base64_decode(key); data = [RSA stripPrivateKeyHeader:data]; if(!data){ return nil; } //a tag to read/write keychain storage NSString *tag = @"RSAUtil_PrivKey"; NSData *d_tag = [NSData dataWithBytes:[tag UTF8String] length:[tag length]]; // Delete any old lingering key with the same tag NSMutableDictionary *privateKey = [[NSMutableDictionary alloc] init]; [privateKey setObject:(__bridge id) kSecClassKey forKey:(__bridge id)kSecClass]; [privateKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType]; [privateKey setObject:d_tag forKey:(__bridge id)kSecAttrApplicationTag]; SecItemDelete((__bridge CFDictionaryRef)privateKey); // Add persistent version of the key to system keychain [privateKey setObject:data forKey:(__bridge id)kSecValueData]; [privateKey setObject:(__bridge id) kSecAttrKeyClassPrivate forKey:(__bridge id) kSecAttrKeyClass]; [privateKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id) kSecReturnPersistentRef]; CFTypeRef persistKey = nil; OSStatus status = SecItemAdd((__bridge CFDictionaryRef)privateKey, &persistKey); if (persistKey != nil){ CFRelease(persistKey); } if ((status != noErr) && (status != errSecDuplicateItem)) { return nil; } [privateKey removeObjectForKey:(__bridge id)kSecValueData]; [privateKey removeObjectForKey:(__bridge id)kSecReturnPersistentRef]; [privateKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef]; [privateKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType]; // Now fetch the SecKeyRef version of the key SecKeyRef keyRef = nil; status = SecItemCopyMatching((__bridge CFDictionaryRef)privateKey, (CFTypeRef *)&keyRef); if(status != noErr){ return nil; } return keyRef; } /* START: Encryption & Decryption with RSA private key */ + (NSString *)encryptString:(NSString *)str privateKey:(NSString *)privKey{ NSData *data = [RSA encryptData:[str dataUsingEncoding:NSUTF8StringEncoding] privateKey:privKey]; NSString *ret = base64_encode_data(data); return ret; } + (NSData *)encryptData:(NSData *)data privateKey:(NSString *)privKey{ if(!data || !privKey){ return nil; } SecKeyRef keyRef = [RSA addPrivateKey:privKey]; if(!keyRef){ return nil; } const uint8_t *srcbuf = (const uint8_t *)[data bytes]; size_t srclen = (size_t)data.length; size_t outlen = SecKeyGetBlockSize(keyRef) * sizeof(uint8_t); if(srclen > outlen - 11){ CFRelease(keyRef); return nil; } void *outbuf = malloc(outlen); OSStatus status = noErr; status = SecKeyEncrypt(keyRef, kSecPaddingPKCS1, srcbuf, srclen, outbuf, &outlen ); NSData *ret = nil; if (status != 0) { //NSLog(@"SecKeyEncrypt fail. Error Code: %ld", status); }else{ ret = [NSData dataWithBytes:outbuf length:outlen]; } free(outbuf); CFRelease(keyRef); return ret; } + (NSString *)decryptString:(NSString *)str privateKey:(NSString *)privKey{ NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters]; data = [RSA decryptData:data privateKey:privKey]; NSString *ret = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; return ret; } + (NSData *)decryptData:(NSData *)data privateKey:(NSString *)privKey{ if(!data || !privKey){ return nil; } SecKeyRef keyRef = [RSA addPrivateKey:privKey]; if(!keyRef){ return nil; } const uint8_t *srcbuf = (const uint8_t *)[data bytes]; size_t srclen = (size_t)data.length; size_t outlen = SecKeyGetBlockSize(keyRef) * sizeof(uint8_t); if(srclen != outlen){ //TODO currently we are able to decrypt only one block! CFRelease(keyRef); return nil; } UInt8 *outbuf = malloc(outlen); //use kSecPaddingNone in decryption mode OSStatus status = noErr; status = SecKeyDecrypt(keyRef, kSecPaddingNone, srcbuf, srclen, outbuf, &outlen ); NSData *result = nil; if (status != 0) { //NSLog(@"SecKeyEncrypt fail. Error Code: %ld", status); }else{ //the actual decrypted data is in the middle, locate it! int idxFirstZero = -1; int idxNextZero = (int)outlen; for ( int i = 0; i < outlen; i++ ) { if ( outbuf[i] == 0 ) { if ( idxFirstZero < 0 ) { idxFirstZero = i; } else { idxNextZero = i; break; } } } result = [NSData dataWithBytes:&outbuf[idxFirstZero+1] length:idxNextZero-idxFirstZero-1]; } free(outbuf); CFRelease(keyRef); return result; } /* END: Encryption & Decryption with RSA private key */ /* START: Encryption & Decryption with RSA public key */ + (NSString *)encryptString:(NSString *)str publicKey:(NSString *)pubKey{ NSData *data = [RSA encryptData:[str dataUsingEncoding:NSUTF8StringEncoding] publicKey:pubKey]; NSString *ret = base64_encode_data(data); return ret; } + (NSData *)encryptData:(NSData *)data publicKey:(NSString *)pubKey{ if(!data || !pubKey){ return nil; } SecKeyRef keyRef = [RSA addPublicKey:pubKey]; if(!keyRef){ return nil; } const uint8_t *srcbuf = (const uint8_t *)[data bytes]; size_t srclen = (size_t)data.length; size_t outlen = SecKeyGetBlockSize(keyRef) * sizeof(uint8_t); if(srclen > outlen - 11){ CFRelease(keyRef); return nil; } void *outbuf = malloc(outlen); OSStatus status = noErr; status = SecKeyEncrypt(keyRef, kSecPaddingPKCS1, srcbuf, srclen, outbuf, &outlen ); NSData *ret = nil; if (status != 0) { //NSLog(@"SecKeyEncrypt fail. Error Code: %ld", status); }else{ ret = [NSData dataWithBytes:outbuf length:outlen]; } free(outbuf); CFRelease(keyRef); return ret; } + (NSString *)decryptString:(NSString *)str publicKey:(NSString *)pubKey{ NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters]; data = [RSA decryptData:data publicKey:pubKey]; NSString *ret = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; return ret; } + (NSData *)decryptData:(NSData *)data publicKey:(NSString *)pubKey{ if(!data || !pubKey){ return nil; } SecKeyRef keyRef = [RSA addPublicKey:pubKey]; if(!keyRef){ return nil; } const uint8_t *srcbuf = (const uint8_t *)[data bytes]; size_t srclen = (size_t)data.length; size_t outlen = SecKeyGetBlockSize(keyRef) * sizeof(uint8_t); if(srclen != outlen){ //TODO currently we are able to decrypt only one block! CFRelease(keyRef); return nil; } UInt8 *outbuf = malloc(outlen); //use kSecPaddingNone in decryption mode OSStatus status = noErr; status = SecKeyDecrypt(keyRef, kSecPaddingNone, srcbuf, srclen, outbuf, &outlen ); NSData *result = nil; if (status != 0) { //NSLog(@"SecKeyEncrypt fail. Error Code: %ld", status); }else{ //the actual decrypted data is in the middle, locate it! int idxFirstZero = -1; int idxNextZero = (int)outlen; for ( int i = 0; i < outlen; i++ ) { if ( outbuf[i] == 0 ) { if ( idxFirstZero < 0 ) { idxFirstZero = i; } else { idxNextZero = i; break; } } } result = [NSData dataWithBytes:&outbuf[idxFirstZero+1] length:idxNextZero-idxFirstZero-1]; } free(outbuf); CFRelease(keyRef); return result; } /* END: Encryption & Decryption with RSA public key */ @end
NSString *pubkey = @"-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDEChqe80lJLTTkJD3X3Lyd7Fj+\nzuOhDZkjuLNPog3YR20e5JcrdqI9IFzNbACY/GQVhbnbvBqYgyql8DfPCGXpn0+X\nNSxELIUw9Vh32QuhGNr3/TBpechrVeVpFPLwyaYNEk1CawgHCeQqf5uaqiaoBDOT\nqeox88Lc1ld7MsfggQIDAQAB\n-----END PUBLIC KEY-----"; NSString *privkey = @"-----BEGIN RSA PRIVATE KEY-----\nMIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMQKGp7zSUktNOQk\nPdfcvJ3sWP7O46ENmSO4s0+iDdhHbR7klyt2oj0gXM1sAJj8ZBWFudu8GpiDKqXw\nN88IZemfT5c1LEQshTD1WHfZC6EY2vf9MGl5yGtV5WkU8vDJpg0STUJrCAcJ5Cp/\nm5qqJqgEM5Op6jHzwtzWV3syx+CBAgMBAAECgYEApSzqPzE3d3uqi+tpXB71oY5J\ncfB55PIjLPDrzFX7mlacP6JVKN7dVemVp9OvMTe/UE8LSXRVaFlkLsqXC07FJjhu\nwFXHPdnUf5sanLLdnzt3Mc8vMgUamGJl+er0wdzxM1kPTh0Tmq+DSlu5TlopAHd5\nIqF3DYiORIen3xIwp0ECQQDj6GFaXWzWAu5oUq6j1msTRV3mRZnx8Amxt1ssYM0+\nJLf6QYmpkGFqiQOhHkMgVUwRFqJC8A9EVR1eqabcBXbpAkEA3DQfLVr94vsIWL6+\nVrFcPJW9Xk28CNY6Xnvkin815o2Q0JUHIIIod1eVKCiYDUzZAYAsW0gefJ49sJ4Y\niRJN2QJAKuxeQX2s/NWKfz1rRNIiUnvTBoZ/SvCxcrYcxsvoe9bAi7KCMdxObJkn\nhNXFQLav39wKbV73ESCSqnx7P58L2QJABmhR2+0A5EDvvj1WpokkqPKmfv7+ELfD\nHQq33LvU4q+N3jPn8C85ZDedNHzx57kru1pyb/mKQZANNX10M1DgCQJBAMKn0lEx\nQH2GrkjeWgGVpPZkp0YC+ztNjaUMJmY5g0INUlDgqTWFNftxe8ROvt7JtUvlgtKC\nXdXQrKaEnpebeUQ=\n-----END RSA PRIVATE KEY-----"; NSString *originString = @"hello world!"; NSString *encWithPubKey; NSString *decWithPrivKey; NSString *encWithPrivKey; NSString *decWithPublicKey; NSLog(@"Original string: %@", originString); // Demo: encrypt with public key encWithPubKey = [RSA encryptString:originString publicKey:pubkey]; NSLog(@"Enctypted with public key: %@", encWithPubKey); // Demo: decrypt with private key decWithPrivKey = [RSA decryptString:encWithPubKey privateKey:privkey]; NSLog(@"Decrypted with private key: %@", decWithPrivKey); // by PHP encWithPubKey = @"p1i8zlbzjy9e8PI0hsmVZUNLNy0jr7KpbsDoKek1FvHpnPXkk1W+91mizj6aD+7n7UkE2G5OrrmqaQSQzMEXOv+zgyGQH0x1AlbCYg0YAFdoOiOOUuNS4Gb9ltFmjy9pGf5mqCcr33h14Ln3l5MZGylyoSmIDpooDCk2t/BJHnU="; decWithPrivKey = [RSA decryptString:encWithPubKey privateKey:privkey]; NSLog(@"(PHP enc)Decrypted with private key: %@", decWithPrivKey); // Demo: encrypt with private key // TODO: encryption with private key currently NOT WORKING YET! //encWithPrivKey = [RSA encryptString:originString privateKey:privkey]; //NSLog(@"Enctypted with private key: %@", encWithPrivKey); // Demo: decrypt with public key encWithPrivKey = @"F+feHOH6807tUV/drvepAMzKlVKRsoDFRkFNfhS9kgVoBt2E6OnUIVw12l608yQGWiqtq8rgZgMY/VCQYZB+3r2rhDlyZ2fjo00sUFOp5BkNPFTs/NpQAolD6V3ifNgDmBQP92uVbxbod1pLRwLC0wLOhr5flQXvvobeg5KrDeE="; decWithPublicKey = [RSA decryptString:encWithPrivKey publicKey:pubkey]; NSLog(@"(PHP enc)Decrypted with public key: %@", decWithPublicKey);
安卓版 ,公钥一键加密解密 。需要下载org.bouncycastle.jce.provider.BouncyCastleProvider.jar包用于初始化
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.math.BigInteger; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.RSAPublicKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; /** * @author Young * @date * 一键加密解密 安卓版 */ public final class RSAUtils { private static String RSA = "RSA"; private static PublicKey publicKey; /** * 随机生成RSA密钥对(默认密钥长度为1024) * * @return */ private static KeyPair generateRSAKeyPair() { return generateRSAKeyPair(1024); } /** * 随机生成RSA密钥对 * * @param keyLength * 密钥长度,范围:512~2048<br> * 一般1024 * @return */ private static KeyPair generateRSAKeyPair(int keyLength) { try { KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA,new org.bouncycastle.jce.provider.BouncyCastleProvider()); kpg.initialize(keyLength); return kpg.genKeyPair(); } catch (Throwable e) { e.printStackTrace(); return null; } } /** * 用公钥加密 <br> * 每次加密的字节数,不能超过密钥的长度值减去11 * * @return 加密后的 数据 */ public static String encryptData(String data ) { try { if (publicKey==null) { publicKey=loadPublicKey(Constants.getPBK()); } // Cipher cipher = Cipher.getInstance(RSA); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); // 编码前设定编码方式及密钥 cipher.init(Cipher.ENCRYPT_MODE, publicKey); // 传入编码数据并返回编码结果 return Base64Utils.encode(cipher.doFinal(data.getBytes())); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 用公钥解密 * * @return */ public static String decryptData(String data) { try { if (publicKey==null) { publicKey=loadPublicKey(Constants.getPBK()); } byte[] encryptedData=Base64Utils.decode(data); // Cipher cipher = Cipher.getInstance(RSA); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.DECRYPT_MODE, publicKey); return new String(cipher.doFinal(encryptedData)); } catch (Exception e) { return null; } } /** * 通过公钥byte[](publicKey.getEncoded())将公钥还原,适用于RSA算法 * * @param keyBytes * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException */ private static PublicKey getPublicKey(byte[] keyBytes) throws NoSuchAlgorithmException, InvalidKeySpecException { X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(RSA); PublicKey publicKey = keyFactory.generatePublic(keySpec); return publicKey; } /** * 通过私钥byte[]将公钥还原,适用于RSA算法 * * @param keyBytes * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException */ private static PrivateKey getPrivateKey(byte[] keyBytes) throws NoSuchAlgorithmException, InvalidKeySpecException { PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(RSA); PrivateKey privateKey = keyFactory.generatePrivate(keySpec); return privateKey; } /** * 使用N、e值还原公钥 * * @param modulus * @param publicExponent * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException */ private static PublicKey getPublicKey(String modulus, String publicExponent) throws NoSuchAlgorithmException, InvalidKeySpecException { BigInteger bigIntModulus = new BigInteger(modulus); BigInteger bigIntPrivateExponent = new BigInteger(publicExponent); RSAPublicKeySpec keySpec = new RSAPublicKeySpec(bigIntModulus, bigIntPrivateExponent); KeyFactory keyFactory = KeyFactory.getInstance(RSA); PublicKey publicKey = keyFactory.generatePublic(keySpec); return publicKey; } /** * 使用N、d值还原私钥 * * @param modulus * @param privateExponent * @return * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException */ private static PrivateKey getPrivateKey(String modulus, String privateExponent) throws NoSuchAlgorithmException, InvalidKeySpecException { BigInteger bigIntModulus = new BigInteger(modulus); BigInteger bigIntPrivateExponent = new BigInteger(privateExponent); RSAPublicKeySpec keySpec = new RSAPublicKeySpec(bigIntModulus, bigIntPrivateExponent); KeyFactory keyFactory = KeyFactory.getInstance(RSA); PrivateKey privateKey = keyFactory.generatePrivate(keySpec); return privateKey; } /** * 从字符串中加载公钥 * * @param publicKeyStr * 公钥数据字符串 * @throws Exception * 加载公钥时产生的异常 */ private static PublicKey loadPublicKey(String publicKeyStr) throws Exception { try { byte[] buffer = Base64Utils.decode(publicKeyStr); KeyFactory keyFactory = KeyFactory.getInstance(RSA); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer); return (RSAPublicKey) keyFactory.generatePublic(keySpec); } catch (NoSuchAlgorithmException e) { throw new Exception("无此算法"); } catch (InvalidKeySpecException e) { throw new Exception("公钥非法"); } catch (NullPointerException e) { throw new Exception("公钥数据为空"); } } /** * 从字符串中加载私钥<br> * 加载时使用的是PKCS8EncodedKeySpec(PKCS#8编码的Key指令)。 * * @param privateKeyStr * @return * @throws Exception */ private static PrivateKey loadPrivateKey(String privateKeyStr) throws Exception { try { byte[] buffer = Base64Utils.decode(privateKeyStr); // X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer); KeyFactory keyFactory = KeyFactory.getInstance(RSA); return (RSAPrivateKey) keyFactory.generatePrivate(keySpec); } catch (NoSuchAlgorithmException e) { throw new Exception("无此算法"); } catch (InvalidKeySpecException e) { throw new Exception("私钥非法"); } catch (NullPointerException e) { throw new Exception("私钥数据为空"); } } /** * 从文件中输入流中加载公钥 * * @param in * 公钥输入流 * @throws Exception * 加载公钥时产生的异常 */ private static PublicKey loadPublicKey(InputStream in) throws Exception { try { return loadPublicKey(readKey(in)); } catch (IOException e) { throw new Exception("公钥数据流读取错误"); } catch (NullPointerException e) { throw new Exception("公钥输入流为空"); } } /** * 从文件中加载私钥 * * @param keyFileName * 私钥文件名 * @return 是否成功 * @throws Exception */ private static PrivateKey loadPrivateKey(InputStream in) throws Exception { try { return loadPrivateKey(readKey(in)); } catch (IOException e) { throw new Exception("私钥数据读取错误"); } catch (NullPointerException e) { throw new Exception("私钥输入流为空"); } } /** * 读取密钥信息 * * @param in * @return * @throws IOException */ private static String readKey(InputStream in) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(in)); String readLine = null; StringBuilder sb = new StringBuilder(); while ((readLine = br.readLine()) != null) { if (readLine.charAt(0) == '-') { continue; } else { sb.append(readLine); sb.append('\r'); } } br.close(); return sb.toString(); } /** * 打印公钥信息 * * @param publicKey */ private static void printPublicKeyInfo(PublicKey publicKey) { RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey; System.out.println("----------RSAPublicKey----------"); System.out.println("Modulus.length=" + rsaPublicKey.getModulus().bitLength()); System.out.println("Modulus=" + rsaPublicKey.getModulus().toString()); System.out.println("PublicExponent.length=" + rsaPublicKey.getPublicExponent().bitLength()); System.out.println("PublicExponent=" + rsaPublicKey.getPublicExponent().toString()); } private static void printPrivateKeyInfo(PrivateKey privateKey) { RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey; System.out.println("----------RSAPrivateKey ----------"); System.out.println("Modulus.length=" + rsaPrivateKey.getModulus().bitLength()); System.out.println("Modulus=" + rsaPrivateKey.getModulus().toString()); System.out.println("PrivateExponent.length=" + rsaPrivateKey.getPrivateExponent().bitLength()); System.out.println("PrivatecExponent=" + rsaPrivateKey.getPrivateExponent().toString()); } }
public static String getPBK(){ /* 注意这里 开头结尾没有----------- , 中间也没有\n换行符 */ return "MIGfMA0GCSqGSIb.........省去中了间部分..........eox88Lc1ld7MsfggQIDAQAB"; }
java web 版
/** * BASE64转换工具 * */ public class Base64Util { private static final char intToBase64[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; private static final byte base64ToInt[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 }; /** * byte数组转换成BASE64字符串 * * @param data byte数组 * @return <b>String</b> BASE64字符串<b><br/>null</b> 转换失败 */ public static String byteArrayToBase64(byte[] data) { if(data==null || data.length==0){ return null; } int len = data.length; int groups = len/3; int nogroups = len-3*groups; int resultLen = (len+2)/3*4; StringBuffer result = new StringBuffer(resultLen); int cursor = 0; for(int i=0;i<groups;i++){ int byte0 = data[cursor++]&0xff; int byte1 = data[cursor++]&0xff; int byte2 = data[cursor++]&0xff; result.append(intToBase64[byte0>>2]); result.append(intToBase64[(byte0<<4)&0x3f|(byte1>>4)]); result.append(intToBase64[(byte1<<2)&0x3f|(byte2>>6)]); result.append(intToBase64[byte2&0x3f]); } if(nogroups!=0){ int byte0 = data[cursor++]&0xff; result.append(intToBase64[byte0>>2]); if(nogroups==1){ result.append(intToBase64[(byte0<<4)&0x3f]); result.append("=="); }else{ int byte1 = data[cursor++]&0xff; result.append(intToBase64[(byte0<<4)&0x3f|(byte1>>4)]); result.append(intToBase64[(byte1<<2)&0x3f]); result.append('='); } } return result.toString(); } /** * BASE64字符串转换成byte数组 * * @param data BASE64字符串 * @return <b>String</b> byte数组<b><br/>null</b> 转换失败 */ public static byte[] base64ToByteArray(String data) { if(StringUtil.isEmpty(data)){ return null; } int len = data.length(); int groups = len/4; if(groups*4!=len){ return null; } int nogroups = 0; int fullGroups = groups; if(len!=0){ if(data.charAt(len-1)=='='){ nogroups++; fullGroups--; } if(data.charAt(len-2)=='='){ nogroups++; } } byte[] result = new byte[groups*3-nogroups]; int inCursor = 0; int outCursor = 0; try { for(int i=0;i<fullGroups;i++){ int ch0 = base64toInt(data.charAt(inCursor++)); int ch1 = base64toInt(data.charAt(inCursor++)); int ch2 = base64toInt(data.charAt(inCursor++)); int ch3 = base64toInt(data.charAt(inCursor++)); result[outCursor++] = (byte) ((ch0<<2)|(ch1>>4)); result[outCursor++] = (byte) ((ch1<<4)|(ch2>>2)); result[outCursor++] = (byte) ((ch2<<6)|ch3); } if(nogroups!=0){ int ch0 = base64toInt(data.charAt(inCursor++)); int ch1 = base64toInt(data.charAt(inCursor++)); result[outCursor++] = (byte) ((ch0<<2)|(ch1>>4)); if(nogroups==1){ int ch2 = base64toInt(data.charAt(inCursor++)); result[outCursor++] = (byte) ((ch1<<4)|(ch2>>2)); } } } catch (Exception e) { return null; } return result; } private static int base64toInt(char c) { int result = base64ToInt[c]; if(result<0){ throw new RuntimeException(); } return result; } }
import java.math.BigInteger; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.SecureRandom; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; import com.yagou.base.entity.Charset; /** * RSA加密解密工具 * */ public class RsaUtil { /** * 私钥加密 * * @param key 私钥 * @param data 明文 * @return <b>String</b> 密文<b><br/>null</b> 加密失败 */ public static String encryptByPrivateKey(String key, byte[] data) { try { RSAPrivateKey privateKey = getPrivateKey(key); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, privateKey); byte[] rsa = cipher.doFinal(data); return Base64Util.byteArrayToBase64(rsa); } catch (Exception e) { } return null; } /** * 私钥加密 * * @param key 私钥 * @param data 明文 * @return <b>String</b> 密文<b><br/>null</b> 加密失败 */ public static String encryptByPrivateKey(String key, String data) { try { byte[] bdata = StringUtil.strToByte(data); RSAPrivateKey privateKey = getPrivateKey(key); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, privateKey); byte[] rsa = cipher.doFinal(bdata); return Base64Util.byteArrayToBase64(rsa); } catch (Exception e) { } return null; } /** * 公钥加密 * * @param key 公钥 * @param data 明文 * @return <b>String</b> 密文<b><br/>null</b> 加密失败 */ public static String encryptByPublicKey(String key, byte[] data) { try { RSAPublicKey publicKey = getPublicKey(key); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] rsa = cipher.doFinal(data); return Base64Util.byteArrayToBase64(rsa); } catch (Exception e) { } return null; } /** * 公钥加密 * * @param key 公钥 * @param data 明文 * @return <b>String</b> 密文<b><br/>null</b> 加密失败 */ public static String encryptByPublicKey(String key, String data) { try { byte[] bdata = StringUtil.strToByte(data); RSAPublicKey publicKey = getPublicKey(key); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] rsa = cipher.doFinal(bdata); return Base64Util.byteArrayToBase64(rsa); } catch (Exception e) { } return null; } /** * 私钥解密 * * @param key 私钥 * @param data 密文 * @return <b>String</b> 明文<b><br/>null</b> 解密失败 */ public static String decryptByPrivateKey(String key, byte[] data) { try { RSAPrivateKey privateKey = getPrivateKey(key); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] rsa = cipher.doFinal(data); return new String(rsa, Charset.UTF8.getCharset()); } catch (Exception e) { } return null; } /** * 私钥解密 * * @param key 私钥 * @param data 密文 * @return <b>String</b> 明文<b><br/>null</b> 解密失败 */ public static String decryptByPrivateKey(String key, String data) { try { byte[] bdata = Base64Util.base64ToByteArray(data); RSAPrivateKey privateKey = getPrivateKey(key); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] rsa = cipher.doFinal(bdata); return new String(rsa, Charset.UTF8.getCharset()); } catch (Exception e) { } return null; } /** * 公钥解密 * * @param key 公钥 * @param data 密文 * @return <b>String</b> 明文<b><br/>null</b> 解密失败 */ public static String decryptByPublicKey(String key, byte[] data) { try { RSAPublicKey publicKey = getPublicKey(key); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.DECRYPT_MODE, publicKey); byte[] rsa = cipher.doFinal(data); return new String(rsa, Charset.UTF8.getCharset()); } catch (Exception e) { } return null; } /** * 公钥解密 * * @param key 公钥 * @param data 密文 * @return <b>String</b> 明文<b><br/>null</b> 解密失败 */ public static String decryptByPublicKey(String key, String data) { try { byte[] bdata = Base64Util.base64ToByteArray(data); RSAPublicKey publicKey = getPublicKey(key); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.DECRYPT_MODE, publicKey); byte[] rsa = cipher.doFinal(bdata); return new String(rsa, Charset.UTF8.getCharset()); } catch (Exception e) { } return null; } /** * JS密钥对 * * @param size 密钥长度 * @return 密钥对 */ public static Map<String, String> genJsKey(int size) { Map<String, String> keyMap = new HashMap<String, String>(); try { KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA"); keygen.initialize(size, new SecureRandom()); KeyPair keyPair = keygen.generateKeyPair(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); BigInteger n = privateKey.getModulus(); BigInteger e = publicKey.getPublicExponent(); BigInteger d = privateKey.getPrivateExponent(); String p = Base64Util.byteArrayToBase64(privateKey.getEncoded()); keyMap.put("n", n.toString(16)); keyMap.put("e", e.toString(16)); keyMap.put("d", d.toString(16)); keyMap.put("p", p); } catch (Exception e) { } return keyMap; } /** * JS密文解密 * * @param key 私钥 * @param data 密文 * @return <b>String</b> 明文<b><br/>null</b> 解密失败 */ public static String decryptJsData(String key, String data) { try { byte[] bdata = hexToByte(StringUtil.strToByte(data)); RSAPrivateKey privateKey = getPrivateKey(key); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] rsa = cipher.doFinal(bdata); return new String(rsa, Charset.UTF8.getCharset()); } catch (Exception e) { } return null; } private static RSAPrivateKey getPrivateKey(String key) { try { byte[] keyBytes = Base64Util.base64ToByteArray(key); PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory factory = KeyFactory.getInstance("RSA"); return (RSAPrivateKey) factory.generatePrivate(spec); } catch (Exception e) { } return null; } private static RSAPublicKey getPublicKey(String key) { try { byte[] keyBytes = Base64Util.base64ToByteArray(key); X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes); KeyFactory factory = KeyFactory.getInstance("RSA"); return (RSAPublicKey) factory.generatePublic(spec); } catch (Exception e) { } return null; } private static byte[] hexToByte(byte[] hex){ if(hex.length%2!=0){ return null; } byte[] b = new byte[hex.length/2]; for(int i=0;i<hex.length;i+=2){ String str = new String(hex, i, 2); b[i/2] = (byte) Integer.parseInt(str, 16); } return b; } }
import java.net.URLEncoder; import java.util.UUID; import com.yagou.base.entity.Charset; /** * 字符串工具 * */ public class StringUtil { /** * 获得32位唯一ID * * @return */ public static String getUUID() { return UUID.randomUUID().toString().replaceAll("-", ""); } /** * 判断字符串是否为空 * * @param value * @return */ public static boolean isEmpty(String value) { if(value==null || value.trim().length()==0){ return true; } return false; } /** * 获得字符串长度<br /> * 中文长度为3,其他长度1 * * @param value * @return */ public static int strLen(String value) { if(isEmpty(value)){ return 0; } int len = 0; String chinese = "[\u0391-\uFFE5]"; for(int i=0;i<value.length();i++){ String str = value.substring(i, i+1); if(str.matches(chinese)){ len += 3; }else{ len += 1; } } return len; } /** * 字符串转Integer * * @param value * @return */ public static Integer strToInt(String value) { try { return Integer.parseInt(value); } catch (Exception e) { } return null; } /** * 字符串转Long * * @param value * @return */ public static Long strToLong(String value) { try { return Long.parseLong(value); } catch (Exception e) { } return null; } /** * 获得字符串编码格式<br /> * 编码格式可为utf-8|iso-8859-1 * * @param value * @return */ public static Charset getEncode(String value) { if(isEmpty(value)){ return null; } if(value.matches("^[\u0000-\u0080]+$")){ return Charset.UTF8; } Charset encode = Charset.ISO8859; try { if(value.equals(new String(value.getBytes(encode.getCharset()), encode.getCharset()))){ return encode; } } catch (Exception e) { } encode = Charset.UTF8; try { if(value.equals(new String(value.getBytes(encode.getCharset()), encode.getCharset()))){ return encode; } } catch (Exception e) { } return null; } /** * 识别字符串编码并重新编码成utf-8格式<br /> * 原编码格式可为utf-8|iso-8859-1 * * @param value * @return */ public static String encodeToUtf8(String value) { try { Charset encode = getEncode(value); if(encode!=null && !Charset.UTF8.getCharset().equals(encode.getCharset())){ value = new String(value.getBytes(encode.getCharset()), Charset.UTF8.getCharset()); return value; } } catch (Exception e) { } return value; } /** * URL编码 * * @param url * @return */ public static String urlEncode(String url) { try { return URLEncoder.encode(url, Charset.UTF8.getCharset()); } catch (Exception e) { return null; } } /** * byte数组转字符串 * * @param value * @return */ public static String byteToStr(byte[] value) { try { return new String(value, Charset.UTF8.getCharset()); } catch (Exception e) { return null; } } /** * 字符串转byte数组 * * @param value * @return */ public static byte[] strToByte(String value) { try { return value.getBytes(Charset.UTF8.getCharset()); } catch (Exception e) { return null; } } }
/** */ public class RsaKey { /* 注意这里 开头结尾没有----------- , 中间也没有\n换行符 */ public static final String privateKey = "MIICdgIBADANBgkqhkiGKGsQiUpcZOn/U5。。。。。。。。ffQJAX10xxSrVsEYNZH3iDVCy3g=="; public static final String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA。。。。。。。。。。。mFZDj0LdC91+YMPKPnMiECf7I+FYI5rTWdlDAELPawIDAQAB"; }
使用:
//RSA加密后的字符串 String pwd="QAF3LNljSQDWYaOOsliW1u+J++Du5xyTnyuNgAl8FGAfm3mPjLEFrfA1cPsa2gwyirHzCpGTv0WnRIobXWnI3UsXwAvRBtOcWRscJjMDlF7ad5+tly0zUwPJvrvd5Vm1ViilqaOEiPHTTZqzLdZvSK/zofgr6D4jqx8+TF6GdNc="; String s2=RsaUtil.decryptByPrivateKey(RsaKey.privateKey, pwd); System.out.println(s2);
亲测该套RSA加密在ios、 安卓双平台,javaweb服务器的环境下有效