发布于2023-09-25 20:20 阅读(1091) 评论(0) 点赞(26) 收藏(0)
我RSA encryption
在 中实现和解密时遇到了麻烦Objective-C
,我做得Java
非常简单,现在我尝试java
在 中翻译这段代码objc
。这是我的java
代码:
public static byte[] encryptRSA(byte[] text, PublicKey key) throws Exception {
byte[] cipherText = null;
// get an RSA cipher object and print the provider
Cipher cipher = Cipher.getInstance("RSA");
// encrypt the plaintext using the public key
cipher.init(Cipher.ENCRYPT_MODE, key);
cipherText = cipher.doFinal(text);
return cipherText;
}
public static byte[] decryptRSA(byte[] text, PrivateKey key) throws Exception {
byte[] dectyptedText = null;
// decrypt the text using the private key
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, key);
dectyptedText = cipher.doFinal(text);
return dectyptedText;
}
这就是我生成密钥对的方式
String seed = "SOMERANDOMSEED"+Long.toString(System.currentTimeMillis());
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
SecureRandom rand = new SecureRandom(seed.getBytes());
keyGen.initialize(4096,rand);
KeyPair keyPair = keyGen.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
现在在objC中我已经编写了一些sem可以工作的代码,但我不知道如何从种子生成rsa,就像我在java中所做的那样,以及如何使用此方法导入我在java中保存的密钥
//for import
public static byte[] hexStringToByteArray(String s) {
byte[] b = new byte[s.length() / 2];
for (int i = 0; i < b.length; i++) {
int index = i * 2;
int v = Integer.parseInt(s.substring(index, index + 2), 16);
b[i] = (byte) v;
}
return b;
}
//for export
public static String byteArrayToHexString(byte[] b) {
StringBuilder sb = new StringBuilder(b.length * 2);
for (int i = 0; i < b.length; i++) {
int v = b[i] & 0xff;
if (v < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(v));
}
return sb.toString().toUpperCase();
}
这是我的 objc 代码
//this works properly
+(NSString *)decryptRSA:(NSString *)cipherString key:(SecKeyRef) privateKey {
size_t plainBufferSize = SecKeyGetBlockSize(privateKey);
uint8_t *plainBuffer = malloc(plainBufferSize);
NSData *incomingData = [cipherString decodeFromHexidecimal];
uint8_t *cipherBuffer = (uint8_t*)[incomingData bytes];
size_t cipherBufferSize = SecKeyGetBlockSize(privateKey);
SecKeyDecrypt(privateKey,
kSecPaddingOAEPKey,
cipherBuffer,
cipherBufferSize,
plainBuffer,
&plainBufferSize);
NSData *decryptedData = [NSData dataWithBytes:plainBuffer length:plainBufferSize];
NSString *decryptedString = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
return decryptedString;
}
//this works properly
+(NSString *)encryptRSA:(NSString *)plainTextString key:(SecKeyRef)publicKey {
size_t cipherBufferSize = SecKeyGetBlockSize(publicKey);
uint8_t *cipherBuffer = malloc(cipherBufferSize);
uint8_t *nonce = (uint8_t *)[plainTextString UTF8String];
SecKeyEncrypt(publicKey,
kSecPaddingOAEPKey,
nonce,
strlen( (char*)nonce ),
&cipherBuffer[0],
&cipherBufferSize);
NSData *encryptedData = [NSData dataWithBytes:cipherBuffer length:cipherBufferSize];
return [encryptedData hexadecimalString];
}
//here i generate the key pair
#define kPublicKeyTag "com.apple.sample.publickey"
#define kPrivateKeyTag "com.apple.sample.privatekey"
//i should use these as seed!?!!?
- (void)generateKeyPair:(NSUInteger)keySize {
OSStatus sanityCheck = noErr;
publicKeyRef = NULL;
privateKeyRef = NULL;
// Container dictionaries.
NSMutableDictionary * privateKeyAttr = [[NSMutableDictionary alloc] init];
NSMutableDictionary * publicKeyAttr = [[NSMutableDictionary alloc] init];
NSMutableDictionary * keyPairAttr = [[NSMutableDictionary alloc] init];
// Set top level dictionary for the keypair.
[keyPairAttr setObject:(id)kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];
[keyPairAttr setObject:[NSNumber numberWithUnsignedInteger:keySize] forKey:(id)kSecAttrKeySizeInBits];
// Set the private key dictionary.
[privateKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecAttrIsPermanent];
[privateKeyAttr setObject:privateTag forKey:(id)kSecAttrApplicationTag];
// See SecKey.h to set other flag values.
// Set the public key dictionary.
[publicKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecAttrIsPermanent];
[publicKeyAttr setObject:publicTag forKey:(id)kSecAttrApplicationTag];
// See SecKey.h to set other flag values.
// Set attributes to top level dictionary.
[keyPairAttr setObject:privateKeyAttr forKey:(id)@kSecPrivateKeyAttrs];
[keyPairAttr setObject:publicKeyAttr forKey:(id)@kSecPublicKeyAttrs];
// SecKeyGeneratePair returns the SecKeyRefs just for educational purposes.
sanityCheck = SecKeyGeneratePair((__bridge CFDictionaryRef)keyPairAttr, &publicKeyRef, &privateKeyRef);
}
这是我用来导出 objc 中的键的方法,它看起来就像 java 方法一样工作
+ (NSString *)fromPrivateKeyToString: (SecKeyRef) privateKey {
size_t pkeySize = SecKeyGetBlockSize(privateKey);
NSData* pkeyData = [NSData dataWithBytes:privateKey length:pkeySize];
NSString* pkeyString = [pkeyData hexadecimalString];
return pkeyString;
}
As I explained in my other answer, it is very tricky to generate the same key pair using the same value of the PRNG. But that does not seem to be what you are after. It seems that you want to use your own seeded PRNG to generate the key pair.
In general, the default SecureRandom
in Java is seeded by the operating system. The idea that you can supply your own random number generator is that you may get "better" results using for instance your own entropy pool (e.g. from a a hardware random number generator). Normally the default Java PRNG seeded by the operating system would however provide enough random.
As you are using the SecureRandom
class, you supplant the operating system provided seed with your own relatively weakly seeded PRNG. currentTimeMilis
certainly does not give you much entropy, and the password seems to be static. This is generally not thought to be enough for generating RSA key pairs.
If you really want to you can add some entropy to the pool instead:
// create runtime default PRNG
SecureRandom rng = new SecureRandom();
// make sure that the rng is seeded by the operating system
rng.nextInt();
// add secret to the pool
rng.setSeed("SOME_SECRET".getBytes(StandardCharsets.UTF_8));
// add time information to the pool
rng.setSeed(System.currentTimeMillis());
// use for e.g. RSA key pair generation
There seems to be no method of injecting your own random number generator in Apple's OS X libraries. As indicated, usually the OS provided random number generator is good enough. If you really want to you can write your additional seeds to /dev/random
though.
作者:黑洞官方问答小能手
链接:http://www.javaheidong.com/blog/article/677409/96bfbcd56f32466088e8/
来源:java黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 java黑洞网 All Rights Reserved 版权所有,并保留所有权利。京ICP备18063182号-2
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!