Tôi đang cố triển khai sơ đồ khóa cấp phép đơn giản cho ứng dụng của mình và tôi đang gặp phải những rào cản đáng kể. Tôi đang theo dõi ví dụ tại OpenSSL for License Keys.Sử dụng Chuyển đổi bảo mật để xác minh chữ ký RSA được tạo bằng Ruby/OpenSSL
Vì bài đăng trên blog đó được viết vào năm 2004 và OpenSSL đã không được dùng nữa trên OS X Tôi đang cố sử dụng API chuyển đổi bảo mật để thực hiện xác minh khóa cấp phép thay vì OpenSSL. Tôi đang tạo ra các khóa riêng và công khai với OpenSSL, tuy nhiên; khóa cấp phép được tạo bằng khóa riêng của ứng dụng web Ruby bằng cách sử dụng thư viện trình bao bọc Ruby OpenSSL từ thông báo SHA-256 của địa chỉ email của người mua.
Vấn đề là không có gì tôi làm dường như tạo ra một chữ ký từ Ruby sử dụng OpenSSL rằng Security Transforms API sẽ xác minh.
Các mã Ruby Tôi đang làm việc tắt của là:
require('openssl')
# The email address used as the content of the license key.
license = '[email protected]'
# Generate the public/private keypair.
`openssl genrsa -out private_key.pem 2048`
`openssl rsa -in conductor.pem -out public_key.data -pubout`
# Get the private key and a hash of the license.
private_key = OpenSSL::PKey::RSA.new(File.read('private_key.pem'))
signature = OpenSSL::Digest::SHA256.digest(license)
# The signature passed to SecVerifyTransformCreate in the OS X app. I'm not sure which of these SecVerifyTransformCreate is expecting (the binary digest, a hex representation of the digest, or the original un-digested content), but none of them work.
signature_out = signature
#signature_out = OpenSSL::Digest::SHA256.hexdigest(license)
#signature_out = license
File.write('signature.data', signature_out)
# Sign the email address to generate the license key. Using the OpenSSL::PKey::PKey#sign method produces a license key that can only be verified on the command line by running:
#
# echo -n [email protected] | openssl dgst -sha256 -sign test.pem
#
# while using the #private_encrypt method produces a key that can only be verified on the command line by running:
#
# echo -n [email protected] | openssl dgst -sha256 -binary | openssl rsautl -sign -inkey test.pem
#
# I'm not sure what the exact difference between the two commands above is and why they correspond to the two different Ruby signing methods below. Neither approach produces something that SecVerifyTransformCreate will verify, however.
File.write('license_key.data',
private_key.sign(OpenSSL::Digest::SHA256.new, license))
# private_key.private_encrypt(signature))
Và mã xác nhận tương ứng trong Objective-C:
// Get the data.
NSData *publicKeyData = [NSData dataWithContentsOfFile:@"public_key.data"];
NSData *signatureData = [NSData dataWithContentsOfFile:@"signature.data"];
NSData *licenseKeyData = [NSData dataWithContentsOfFile:@"license_key.data"];
// Import the public key.
SecItemImportExportKeyParameters keyParameters = {};
SecExternalFormat format = kSecFormatOpenSSL;
SecExternalItemType type = kSecItemTypePublicKey;
CFArrayRef publicKeys;
SecItemImport((__bridge CFDataRef)publicKeyData,
NULL,
&format,
&type,
0,
&keyParameters,
NULL,
&publicKeys);
NSArray *publicKeysArray = (__bridge_transfer NSArray *)publicKeys;
SecKeyRef publicKey = (__bridge SecKeyRef)publicKeysArray[0]; // TODO: How do we need to bridge this return value?
CFErrorRef error = NULL;
SecTransformRef verifier = SecVerifyTransformCreate(publicKey, (__bridge CFDataRef)signatureData, &error);
SecTransformSetAttribute(verifier, kSecTransformDebugAttributeName, kCFBooleanTrue, &error);
SecTransformSetAttribute(verifier, kSecTransformInputAttributeName, (__bridge CFDataRef)licenseKeyData, &error);
SecTransformSetAttribute(verifier, kSecDigestTypeAttribute, kSecDigestSHA2, &error);
SecTransformSetAttribute(verifier, kSecDigestLengthAttribute, (__bridge CFNumberRef)@256, &error);
// I'm not sure if one of these transform attributes is necessary, but neither of them produces a verified result anyways.
// SecTransformSetAttribute(verifier, kSecInputIsAttributeName, kSecInputIsDigest, &error);
// SecTransformSetAttribute(verifier, kSecInputIsAttributeName, kSecInputIsRaw, &error);
NSNumber *result = (__bridge NSNumber *)SecTransformExecute(verifier, &error);
NSLog(@"Result: %@", result);
Có ai biết làm thế nào tôi có thể làm công việc này? Tôi đã dành nhiều ngày để đạt được điểm mà tôi đang ở đây và tôi đã cạn kiệt khả năng của tôi để gỡ lỗi này nữa, vì vậy nếu có ai có bất kỳ cái nhìn sâu sắc nó sẽ được đánh giá rất cao!
* "Kể từ bài đăng blog đó được viết vào năm 2004 và OpenSSL đã không còn được sử dụng trên OS X Tôi đang cố gắng sử dụng API chuyển đổi bảo mật để thực hiện xác minh khóa cấp phép thay vì OpenSSL. "* - Một tùy chọn khác là xây dựng phiên bản OpenSSL 1.0.2 trên OS X và sử dụng nó thay thế. Để cấu hình và xây dựng trên OS X, xem [Biên soạn và cài đặt] (https://wiki.openssl.org/index.php/Compilation_and_Installation#Mac) trên wiki OpenSSL. – jww
Cảm ơn bạn đã nhập! Nếu tôi biết những gì tôi biết bây giờ và đã làm điều này để làm hơn một lần nữa, tôi chắc chắn sẽ chỉ liên kết với OpenSSL. Tuy nhiên, Hướng dẫn dịch vụ mã hóa mạnh mẽ khuyến khích bạn sử dụng API chuyển đổi bảo mật và tôi đã cố gắng tránh liên kết một thư viện tĩnh khác với ứng dụng của mình. Tại thời điểm này kể từ khi tôi phần lớn có mã đã được viết với Security Transforms, tôi rất thích tìm ra những gì các mảnh còn thiếu hơn là đi xuống một lỗ thỏ chuyển sang OpenSSL. –
* "Tuy nhiên, Hướng dẫn dịch vụ mã hóa mạnh mẽ khuyến khích bạn sử dụng API chuyển đổi bảo mật ..." * - Vâng, hãy cân nhắc ... Apple không sửa tất cả các lỗi bảo mật của họ, nhưng OpenSSL thực hiện. Ví dụ: một số phiên bản * Giao thông an toàn * của Apple vẫn có lỗi [ECDHE-ECDSA] (https://wiki.openssl.org/index.php/SSL_OP_SAFARI_ECDHE_ECDSA_BUG). Và [CVE-2015-1130 (Hidden Backdoor with Root)] (http://apple.stackexchange.com/q/180396/83961) chỉ được sửa trong một phiên bản nhỏ của hệ điều hành mới nhất. Theo như tôi biết, OpenSSL sửa tất cả các lỗi của chúng (và có rất nhiều lỗi). – jww