Java到Objective-C RSA的实现 [英] Java to Objective-C RSA Implementation

查看:240
本文介绍了Java到Objective-C RSA的实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在实施 RSA加密和解密 Objective-C 时遇到了麻烦,我在 Java 非常简单,现在我试图在 objc java 代码C>。
这是我的 java 代码:

I'm in trouble in implementing RSA encryption and decryption in Objective-C, I made it in Java very simply and now I tried to translate this java code in objc. Here is my java code:

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;

}

这就是我生成密钥对的方式

and this is how i generate the key pair

    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我写了一些sems工作的代码,但我不知道热到从种子生成rsa,就像在java中生成一样,以及如何使用此方法导入我在java中保存的密钥

now in objC I have writed some code that sems to work, but I don't know hot to generate the rsa they from a seed, like i do in java, and how to import the key that i save in java with this method

   //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();
}

这是我的对象代码

//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方法一样工作

this is the method i use to export keys in objc, it seems work just like the java method

+ (NSString *)fromPrivateKeyToString: (SecKeyRef) privateKey {
    size_t pkeySize = SecKeyGetBlockSize(privateKey);
    NSData* pkeyData = [NSData dataWithBytes:privateKey length:pkeySize];
    NSString* pkeyString = [pkeyData hexadecimalString];

    return pkeyString;

}


推荐答案

因为我在我的另一个答案中解释说,使用相同的PRNG值生成相同的密钥对是非常棘手的。但这似乎并不像你追求的那样。您似乎想要使用自己的种子PRNG来生成密钥对。

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.

一般情况下,默认<$ Java中的c $ c> SecureRandom 由操作系统播种。您可以提供自己的随机数生成器的想法是,您可以使用例如您自己的熵池(例如来自硬件随机数生成器)获得更好的结果。通常,操作系统播种的默认Java PRNG会提供足够的随机数。

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.

当您使用 SecureRandom 时类,你取代操作系统提供的种子与你自己相对弱种子的PRNG。 currentTimeMilis 肯定不会给你太多的熵,密码似乎是静态的。这通常被认为不足以生成RSA密钥对。

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






似乎没有方法在Apple的OS X库中注入您自己的随机数生成器。如图所示,通常操作系统提供的随机数生成器就足够了。如果你真的想要,你可以写你的额外种子是 / dev / random 尽管

这篇关于Java到Objective-C RSA的实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆