2015-06-23 19 views
5

Tôi đang cố gắng chuyển đổi khóa RSA công khai đã tạo thành SSH bằng cách sử dụng khung bảo mật Apples.Cách chuyển khóa RSA thành ssh-rsa

Đây là mã tôi đang sử dụng để tạo ra các cặp khóa:

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

Sau đó, tôi kết thúc với một khóa bí mật như thế này:

-----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----- 

Đưa này vào ssh-keygen sản xuất công chúng sau khóa:

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

Câu hỏi của tôi là cách thực hiện ssh-keygen với khung bảo mật của Apple hoặc OpenSSH?

UPDATE:

Tôi bây giờ sử dụng OpenSSL trực tiếp và có được một RSA khóa hợp lệ. Tuy nhiên việc chuyển đổi vẫn không hoạt động chính xác:

- (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];; 
} 

Chìa khóa mới là

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

đó là cách dài hơn nó nên là:

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

Bạn có thể cập nhật cách bạn đã tạo khóa SSH không ?. Tôi đang mắc kẹt với cùng một vấn đề như bạn; ( –

Trả lời

3

Meta: Ít nhất là một phần của câu trả lời, nhưng tôi không biết ObjC để làm cho CW cải thiện.

Lưu ý: Bản sao này gần như trùng lặp với Convert pem key to ssh-rsa format ngoại trừ trong C không ObjC và bắt đầu từ tệp khóa công khai thay vì tệp khóa cá nhân - nhưng cấu trúc trong bộ nhớ OpenSSL cho khóa RSA giống nhau publickey hoặc privatekey, với các trường riêng cho khóa riêng được bỏ qua cho khóa công khai. Và nó có thể được cải thiện.

Mã của bạn (rõ ràng) tạo ra một giá trị chiều dài trong thập phân như 4 chữ số và một chữ số thập phân đại diện của cường độ (không có dấu hiệu vì giá trị luôn luôn là tích cực) cho mỗi e và n, nhưng unbase64'ing đầu ra đã đăng của bạn không hiển thị bất kỳ kết quả nào trong số này thực sự được bao gồm trong kết quả, mà sau khi phần chính xác ban đầu phù hợp với start của bạn dường như là rác và tôi không biết tại sao. Bạn có thể cần một số trợ giúp gỡ lỗi ObjC ở đó.

Dù sao, đúng mã hóa là 4-byte nhị phân (bigendian) chiều dài, theo sau là một nhị phân đại diện bigendian giá trị trong bổ sung hai, mà đòi hỏi phải bổ sung thêm một hàng đầu zero byte cho một số dương trong phạm vi 2 8k/2 đến 2 8k -1; đây thường là trường hợp cho n vì kích thước khóa RSA thường được chọn là bội số của 8 (thực tế là một lũy thừa của 2 hoặc nhiều bội số nhỏ). e là hiếm khi được chọn theo cách này mặc dù nó có thể được. Xem "chuỗi" và "mpint" trong https://tools.ietf.org/html/rfc4251#section-5.

Bạn có thể thực hiện điều này như trong # 1011572 bằng cách gọi số BN_bn2bin để có độ lớn nhị phân lớn thành bộ đệm đủ lớn, sau đó mã hóa độ dài 4 byte, ký hiệu 1 byte và độ lớn, lại thành đủ lớn đệm. Hoặc OpenSSL thực sự có thể làm được nhiều điều này cho bạn; gọi BN_bn2mpi với bộ đệm đủ lớn và nó sẽ làm chiều dài, dấu hiệu và cường độ có thể.

Cách phân bổ và quản lý bộ đệm (s?) Trong ObjC Tôi để lại cho bạn hoặc người khác. Lưu ý rằng cả các trường độ dài và các phần giá trị có thể và thường xuyên sẽ sử dụng byte số không làm giá trị byte hợp lệ; nó không được coi là người kết thúc hoặc đặc biệt. Một chút googling gợi ý cho tôi điều này có thể là một vấn đề cho NSString nhưng tôi có thể dễ dàng bị sai.

0

ssh-keygen làm nó có lẽ sẽ SSH cụ thể và khung bảo mật của Apple có thể không bao gồm điều đó.

Có thể đáng để kiểm tra xem do_print_public trong số ssh-keygen.cwrite_key ở số key.c sẽ làm gì và chỉ sao chép điều đó.

Hoặc xem xét sử dụng chức năng libssh2_userauth_publickey_fromfile của libssh2.

+0

Tôi đặt một cập nhật về câu hỏi của tôi vì nó vẫn không hoạt động.Tôi không thể tìm ra nơi ssh-keygen hiện chuyển đổi. Khi tôi sử dụng cùng một mã tôi kết thúc với một cái gì đó hoàn toàn khác. – btype

Các vấn đề liên quan