Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS-swift-为secp224k1曲线(ECDH)生成密钥对_Ios_Swift_Cryptography_Ecdh - Fatal编程技术网

iOS-swift-为secp224k1曲线(ECDH)生成密钥对

iOS-swift-为secp224k1曲线(ECDH)生成密钥对,ios,swift,cryptography,ecdh,Ios,Swift,Cryptography,Ecdh,我一直在尝试为iOS中的secp224k1曲线生成公钥和私钥。我们正在使用ECDH方法在移动设备和后端之间进行api握手。在Java中,它是使用以下代码完成的 public static KeyPair getECKeyPair() throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException { ECGenParameterSpec ecSpec = new EC

我一直在尝试为iOS中的secp224k1曲线生成公钥和私钥。我们正在使用ECDH方法在移动设备和后端之间进行api握手。在Java中,它是使用以下代码完成的

public static KeyPair getECKeyPair() throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
    ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp224k1");
    KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDH", "SC");
    kpg.initialize(ecSpec);
    return kpg.generateKeyPair();
}
    //Generates public and private key with EC algorithm
public static func getKey() -> [String: SecKey]? {

    let attributes: [String: Any] =
        [kSecAttrKeySizeInBits as String: 256,
         kSecAttrKeyType as String: kSecAttrKeyTypeEC,
         kSecPrivateKeyAttrs as String:
            [kSecAttrIsPermanent as String:    false]
    ]
    var error: Unmanaged<CFError>?
        guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
            let err = error!.takeRetainedValue() as Error
            print(err.localizedDescription)
            return nil
        }
        guard let publicKey = SecKeyCopyPublicKey(privateKey) else {
            print("Error occured while creating public key")
            return nil
        }
        return ["publicKey": publicKey, "privateKey": privateKey]
}
有没有办法在swift中生成具有特定曲线SECP224K1类型的关键点?我尝试使用苹果提供的EC算法,通过使用下面的代码来进行握手

public static KeyPair getECKeyPair() throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
    ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp224k1");
    KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDH", "SC");
    kpg.initialize(ecSpec);
    return kpg.generateKeyPair();
}
    //Generates public and private key with EC algorithm
public static func getKey() -> [String: SecKey]? {

    let attributes: [String: Any] =
        [kSecAttrKeySizeInBits as String: 256,
         kSecAttrKeyType as String: kSecAttrKeyTypeEC,
         kSecPrivateKeyAttrs as String:
            [kSecAttrIsPermanent as String:    false]
    ]
    var error: Unmanaged<CFError>?
        guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
            let err = error!.takeRetainedValue() as Error
            print(err.localizedDescription)
            return nil
        }
        guard let publicKey = SecKeyCopyPublicKey(privateKey) else {
            print("Error occured while creating public key")
            return nil
        }
        return ["publicKey": publicKey, "privateKey": privateKey]
}
我为斯威夫特公司试用了维吉尔加密软件,它几乎解决了这个问题。但它在库中没有我需要的特定曲线类型。它仅支持secp256r1。另外,下面的帖子中的答案我试过了,但没有成功


任何建议或帮助都会很好,谢谢。

iOS不支持Koblitz 224位曲线。一种解决方案可能是使用不同的曲线类型或支持secp224k1的第三方库

从您的意见可以得出结论,secp224k1曲线类型是一种要求

可能使用的第三方库是Virgil Crypto,可通过github获得。它是一个C++库。Virgil Security还提供了一个名为Virgil-crypto-x的Swift包装库,但该库在当前版本中不再支持secp224k1

通过创建具有定义接口的Objective-C++包装器,可以在Swift中间接使用C++LIB

构建VSCCrypto.framework

在命令行上输入:

git clone https://github.com/VirgilSecurity/virgil-crypto
cd virgil-crypto
utils/build.sh --target=ios
这为iOS构建了框架

将VSCCrypto.framework添加到Xcode项目

在项目导航器中选择根节点 在Xcode中创建“新组” 将其命名为“框架” 将文件夹virgil crypto/build/ios/lib中的VSCCrypto.framework拖放到“Frameworks”组中

在右侧的XCode中,在“嵌入式二进制文件”下点击plus

选择VSCCrypto.framework Objective-C++包装器

创建ECDHCrypto Objective-C文件 当询问“是否要配置Objective-C桥接头”时,点击“创建桥接头” 在项目导航器中,将文件后缀从.m更改为.mm以允许C++代码出现。 将import ECDHCrypto.h添加到桥接头中 ECDHCrypto.h

用Java对等测试

要测试密钥交换是否成功,可以执行以下测试:

在Java中,生成secp224k1密钥对,并将公钥输出到控制台

使用复制/粘贴将公钥复制到iOS应用程序的Swift代码中。然后,应用程序生成一个密钥对,并将自己的公钥以及计算出的共享密钥写入控制台。然后将iOS公钥作为绿色显示的输入插入Java程序

最后,可以比较iOS应用程序和Java程序的共享秘密。这里是相同的,因此密钥交换是成功的

在上面的区域中,您可以看到带有iOS源代码的Xcode,在下面的区域中,您可以看到Java程序的输出:


如果您切换到secp521r1,我会专门寻找这种曲线类型;感谢Stephen,我从Virgil获得了以前版本的swift包装器,并修改了一些东西来生成密钥和共享秘密。我不知道我们可以直接使用C++库,直到现在。我试试看,对不起,直到今天我才看到你的答案来奖励赏金。
#import "ECDHCrypto.h"
#import <VSCCrypto/VirgilCrypto.h>

using virgil::crypto::VirgilKeyPair;
using virgil::crypto::VirgilByteArray;
using virgil::crypto::VirgilCipherBase;
using virgil::crypto::str2bytes;
using virgil::crypto::bytes2str;
using virgil::crypto::bytes2hex;


@implementation ECDHCrypto

- (void)generateKeyPair {
    VirgilKeyPair keyPair = VirgilKeyPair::generate(VirgilKeyPair::Type::EC_SECP224K1);

    VirgilByteArray ownPublicKeyBates = keyPair.publicKey();
    self.ownPublicKey = [NSString stringWithCString:bytes2str(ownPublicKeyBates).c_str()
                                           encoding:[NSString defaultCStringEncoding]];

    VirgilByteArray ownPrivateKeyBytes = keyPair.privateKey();
    self.ownPrivateKey = [NSString stringWithCString:bytes2str(ownPrivateKeyBytes).c_str()
                                            encoding:[NSString defaultCStringEncoding]];
}

- (NSString *)shared:(NSString *)otherPublicKey {
    NSAssert(self.ownPrivateKey, @"private key must be set, e.g. use generateKeyPair");
    std::string otherPKString([otherPublicKey cStringUsingEncoding:NSASCIIStringEncoding]);
    VirgilByteArray pubKey = str2bytes(otherPKString);

    std::string ownPrivateKeyString([self.ownPrivateKey cStringUsingEncoding:NSASCIIStringEncoding]);
    VirgilByteArray ownPrivateKeyBytes = str2bytes(ownPrivateKeyString);

    VirgilByteArray shared_ba = VirgilCipherBase::computeShared(pubKey, ownPrivateKeyBytes);

    std::string hex = bytes2hex(shared_ba);
    NSString *shared = [NSString stringWithCString:hex.c_str()
                                          encoding:[NSString defaultCStringEncoding]];

    return shared;
}

@end
let otherPK = """
    -----BEGIN PUBLIC KEY-----
    ME4wEAYHKoZIzj0CAQYFK4EEACADOgAEgeW/foqxCDOd1y6lnXONkRThS6xhjLHP
    SEXs7jHSpoaPQH4vArcGmIb1cAZcepEh7WDQxCyfQXg=
    -----END PUBLIC KEY-----
    """

let ecdhCrypto = ECDHCrypto()
ecdhCrypto.generateKeyPair();
print("ecdhCrypto.ownPublicKey: \n" + ecdhCrypto.ownPublicKey);
print("shared secret: " + ecdhCrypto.shared(otherPK));