Próbuję zaimplementować prosty schemat kluczy licencyjnych dla mojej aplikacji i uruchamiam ważne blokady dróg. Podążam za przykładem pod adresem OpenSSL for License Keys.Korzystanie z funkcji Transformacje zabezpieczeń w celu zweryfikowania podpisu RSA utworzonego przy pomocy Ruby/OpenSSL
Ponieważ ten wpis na blogu został napisany w 2004 roku, a OpenSSL został wycofany w systemie OS X, próbuję użyć interfejsu API Security Transforms do przeprowadzenia weryfikacji klucza licencji zamiast OpenSSL. Generuję klucze prywatne i publiczne z OpenSSL; klucz licencyjny jest generowany przy użyciu klucza prywatnego przez aplikację internetową Ruby z wykorzystaniem biblioteki otworkowej Ruby OpenSSL z streszczenia SHA-256 adresu e-mail nabywcy.
Problem polega na tym, że nic, co robię, nie wydaje się tworzyć podpisu z Ruby przy użyciu OpenSSL, który będzie weryfikowany przez interfejs API Security Transforms.
Kod Ruby Pracuję off to:
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))
i odpowiadający mu kod weryfikacyjny w 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);
Czy ktoś wie, w jaki sposób można dokonać tej pracy? Dosłownie spędziłem kilka dni, dochodząc do punktu, w którym jestem teraz i wyczerpałem moją umiejętność dalszego debagowania, więc jeśli ktokolwiek ma jakąkolwiek wiedzę, byłby ogromnie doceniony!
* "Od ten post został napisany w 2004 roku, a OpenSSL został przestarzały w systemie OS X Próbuję użyć Security Transforms API, aby przeprowadzić weryfikację klucza licencji zamiast OpenSSL. "* - Inną opcją jest zbudowanie wersji OpenSSL 1.0.2 na OS X i użyj go zamiast tego. Aby skonfigurować i budować na OS X, zobacz [Kompilacja i instalacja] (https://wiki.openssl.org/index.php/Compilation_and_Installation#Mac) na wiki OpenSSL. – jww
Dzięki za twój wkład! Gdybym wiedział, co wiem teraz i miałbym to zrobić jeszcze raz, zdecydowanie połączyłbym się z OpenSSL. Jednak Przewodnik po usługach kryptograficznych zdecydowanie zaleca korzystanie z interfejsu API Transform Transforms i próbowałem uniknąć łączenia innej biblioteki statycznej z moją aplikacją. W tym momencie, ponieważ w dużej mierze mam już napisany kod z Security Transforms, chciałbym dowiedzieć się, jaki jest brakujący element, a nie przejść do króliczej dziury przejścia na OpenSSL. –
* "Jednakże Przewodnik po usługach kryptograficznych zdecydowanie zaleca korzystanie z API Security Transforms ..." * - Cóż, rozważ ... Apple nie naprawia wszystkich swoich błędów bezpieczeństwa, ale OpenSSL to robi. Na przykład niektóre wersje programu Apple * Secure Transport * nadal zawierają błąd [ECDHE-ECDSA] (https://wiki.openssl.org/index.php/SSL_OP_SAFARI_ECDHE_ECDSA_BUG). I [CVE-2015-1130 (Ukryty Backdoor z Rootem)] (http://apple.stackexchange.com/q/180396/83961) został naprawiony tylko w jednej niewielkiej wersji najnowszego systemu operacyjnego. O ile mi wiadomo, OpenSSL naprawia wszystkie ich błędy (i jest ich wiele). – jww