簡體   English   中英

如何將RSA密鑰轉換為ssh-rsa

[英]How to convert RSA key to ssh-rsa

我正在嘗試使用Apples安全框架將生成的公共RSA密鑰轉換為SSH。

這是我用於生成密鑰對的代碼:

- (void)generatePrivateKey {
    NSDictionary *privateKeyAttr = @{(__bridge id)kSecAttrIsPermanent: @YES,
                                     (__bridge id)kSecAttrApplicationTag: self.privateTag};
    NSDictionary *publicKeyAttr = @{(__bridge id)kSecAttrIsPermanent: @YES,
                                    (__bridge id)kSecAttrApplicationTag: self.publicTag};


    NSDictionary *keyPairAttr = @{(__bridge id)kSecAttrKeySizeInBits: @1024,
                                  (__bridge id)kSecAttrKeyType: (__bridge id)kSecAttrKeyTypeRSA,
                                  (__bridge id)kSecPrivateKeyAttrs: privateKeyAttr,
                                  (__bridge id)kSecPublicKeyAttrs: publicKeyAttr};

    SecKeyRef publicKey;
    SecKeyRef privateKey;

    SecKeyGeneratePair((__bridge CFDictionaryRef)keyPairAttr, &publicKey, &privateKey);
}

- (NSString *)getPublicKey {
    NSString *contents = [self keyForTag:self.publicTag];
    return [NSString stringWithFormat:@"-----BEGIN RSA PUBLIC KEY-----\n%@\n-----END RSA PUBLIC KEY-----", contents];
}

- (NSString *)getPrivateKey {
    NSString *contents = [self keyForTag:self.privateTag];
    return [NSString stringWithFormat:@"-----BEGIN RSA PRIVATE KEY-----\n%@\n-----END RSA PRIVATE KEY-----", contents];
}

- (NSString *)keyForTag:(NSData *)tag {
    NSDictionary *queryKey = @{(__bridge id)kSecClass: (__bridge id)kSecClassKey,
                                      (__bridge id)kSecAttrApplicationTag: tag,
                                      (__bridge id)kSecAttrKeyType: (__bridge id)kSecAttrKeyTypeRSA,
                                      (__bridge id)kSecReturnData: @YES};

    // Get the key bits.
    CFDataRef keyBits;
    OSStatus sanityCheck = SecItemCopyMatching((__bridge CFDictionaryRef)queryKey, (CFTypeRef *)&keyBits);
    NSData *passDat = (__bridge_transfer NSData *)keyBits;

    if (sanityCheck != noErr) {
        passDat = nil;
    }

    NSString *contents = [passDat base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
    return contents;
}

然后我最終得到一個這樣的私鑰:

-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQD0SvIfWFU1EzKD8rSUMWVcE9t52WtJCIKDyMPYiu3/VV9TBci7
7QocSl400yqjn5eX2piGRO5o/Wh/BKUdC/IzZbAb15jboKvgkE0R+EBnAs+zo2HJ
Y1sZwT4Bc9d1ClvhHpYdE9EwpPc1IIfsz+Sa41Z0wDXqWk90A33BqIcs3wIDAQAB
AoGBAMYvxx4G25mjaWgCjt1q9YAt2/COoqstbDTdu4UBsPNkn2ELYD6Vn440Bxlz
9zOnVaSsgvDrGz+x1gS2D/3woxtuqSHThEOQSHugbtDMEaZ7Pawrj7zVAZQ4PPhD
l9HNf4huhAnvDA9YE73rfQst4+vq0KpPjFHCKcEaQxLu7Y4BAkEB/UeBEdXbJ2e8
ReGmH11/glszpiS+MosJIk/d68la1B5A5gSw6MO4GHNzPUnsNVKJXPYKYPmLDP33
zrYXXXb/MQJAesyFhqM6TtY6IHXQyu43e6iemzAPjx2s9l0SgNAjH25JLS7tHcXo
2gA5JcA+LqS93ei/4lLwOCd7uX9qko2JDwJBARhfdT9MbQqUoaIXSE2cO8aYTyb4
s30/7hdlwNc+UzLUNQZtLrf2iDNt29OyDsiMV/NFwRECUPsmFndG6DYcfQECQHe/
ISZd3eoq9ZvZx7Vb/zbTA3eJsmJ5KcVElVqPnPB1d15cOFWkPKD5PsEVao3JkGzp
HtTw09euiPQm0CIBavkCQQC/GU6l+khFqewNmO5+cok6wSVpqw3paGL8bxIwgifT
yPv42Biyf3gmXtdP//tpyXPlzn6HPqf6PqFGEGvSpPDk
-----END RSA PRIVATE KEY-----

將其放入ssh-keygen會產生以下公鑰:

$ ssh-keygen -f test.p12 -y
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC7VWIi0kXyx/UCGG91iGqKjohRLIj9hp44Xwd/pIApBHo38/noUeqN07S4oGgx47zZthg3zKFP90eEdKKOXZ0yuQKOy+yB5YAYg7e9FVvxfXCOVrGaZohh37HLUql/bdOzTK6/Upjl0ZZNYpxWyfIZ/8jKCAaTG6BhPQhLmWxCQw==

我的問題是如何使用Apple Security框架或OpenSSH執行ssh-keygen

更新:

我現在直接使用OpenSSL並獲得有效的RSA密鑰。 但是轉換仍然無法正常工作:

- (NSString *)publicKey {
    RSA *rsa = self.rsaPrivateKey;

    // Encode the "ssh-rsa" string
    NSMutableData *sshrsa = [[NSMutableData alloc] init];
    const char start[] = {0, 0, 0, 7, 's', 's', 'h', '-', 'r', 's', 'a'};
    [sshrsa appendBytes:start length:sizeof(start)];

    // Encode the RSA encoding exponent e
    {
        const char *e = BN_bn2dec(rsa->e);
        NSString *length = [NSString stringWithFormat:@"%04lu", strlen(e)] ;
        [sshrsa appendData:[length dataUsingEncoding:NSUTF8StringEncoding]];
        [sshrsa appendBytes:e length:strlen(e)];
    }

    // Encode the RSA modul n
    {
        const char *n = BN_bn2dec(rsa->n);
        NSString *length = [NSString stringWithFormat:@"%04lu", strlen(n)] ;
        [sshrsa appendData:[length dataUsingEncoding:NSUTF8StringEncoding]];
        [sshrsa appendBytes:n length:strlen(n)];
    }

    return [sshrsa base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn];;
}

新的關鍵是

ssh-rsa AAAAB3NzaC1yc2EAAAAG4AAAATYwvdcavn8AALOV1CoAAAAG4HHTGr5/AAAwyNcavn8AAPAq1xq+fwAAkPBhBwEAAAC2hnJUVxt7AO3JLixNzOwBALilG75/AABQsaUbvn8AAJC2pRu+fwAAELGlG75/AABZVMwDAQAAAECupRu+fwAAsJsHXP9/AAAIC7kDAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHB3QAAAAAAA2IRA8A/wGr5/AAAAUvAavn8AAJBV4xq+fwAAAFLwGr5/AACQc4Ybvn8AAABS8Bq+fwAAAI4CHr5/AACQc4Ybvn8AAJBzhhu+fwAA4DGwG75/AACfAZIEAQAAAABS8Bq+fwAAUACBG75/AAA9j24JAQAAAFAAgRu+fwAAAFLwGr5/AADgMbAbvn8AAAAAAAAAAAAA4A==

這比它應該的更長:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC+gK0cEEgn/dDk+Sf/AdQtHp2rJoG7DxMuw2hL0+96rdKeixXVXWCE8GqMg7xIU8kSn0lrfcCJDhVBkArmlnlrZDfv1lTItBU7PvV4eDLT+3kApoqYMUmmo/ecDRyAaaOecoVZTl27RZghXcS7yxABlbVhYLzJEywOi46A9yBMFQ==

Meta:至少是答案的一部分,但我不知道ObjC所以讓CW改進。

注意:這幾乎是轉換pem鍵到ssh-rsa格式的重復,除了在C不是ObjC,並且它從一個publickey文件而不是一個私鑰文件開始 - 但是OpenSSL的RSA密鑰的內存結構是對於publickey或privatekey也是如此,對於publickey忽略了privatekey特定的字段。 它可以改進。

您的代碼(顯然)為e和n中的每一個生成一個十進制的長度值作為4位數和一個十進制表示的大小(沒有符號,因為值總是正數),但是unbase64'你的發布輸出沒有顯示任何這些實際上包括在結果中,在正確的初始部分匹配你的start看起來是垃圾,我不知道為什么。 你可能需要一些ObjC調試幫助。

無論如何, 正確的編碼是4字節二進制 (bigendian)長度,然后是二進制 bigendian表示二進制補碼中的值,這需要為2 8k / 2到2 8k范圍內的正數添加前導零字節 - 1; 這通常是n的情況,因為RSA密鑰大小通常選擇為8的倍數(實際上是2的冪或其小倍數)。 e很少以這種方式選擇,盡管它可以。 請參閱https://tools.ietf.org/html/rfc4251#section-5中的 “string”和“mpint”。

您可以通過調用BN_bn2bin將二進制bigendian幅度轉換為足夠大的緩沖區,然后將4字節長度,可能的1字節符號和幅度編碼為足夠大的緩沖區,從而在#1011572中執行此操作。 或者OpenSSL實際上可以為您做很多事情; 使用足夠大的緩沖區調用BN_bn2mpi ,它將執行長度,可能的符號和幅度。

如何在ObjC中分配和管理緩沖區(s?)我留給你或其他人。 請注意,長度字段和值部分都可以並經常使用零字節作為有效字節值; 它不能被視為終結者或其他特殊的。 有點谷歌搜索告訴我這可能NSString的問題,但我很容易出錯。

無論ssh-keygen是什么,它都可能是特定於SSH的,Apple的安全框架可能不會涵蓋這一點。

這可能是值得檢查什么do_print_publicSSH-keygen.cwrite_keykey.c沒有,只是復制。

或者考慮使用libssh2的libssh2_userauth_publickey_fromfile函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM