























https://lekcjaplus.vulcan.net.pl/powiatjaroslawski/mobile-api/Uczen.v3.UczenStart/Certyfikat{
"PIN": "123456",
"TokenKey": "3S100",
"AppVersion": "18.4.1.388",
"DeviceId": "a1ac8990-1f19-1dd7-9c56-2d46def5b346",
"DeviceName": "Nazwa urządzenia",
"DeviceNameUser": "",
"DeviceDescription": "",
"DeviceSystemType": "Android",
"DeviceSystemVersion": "8.0.0",
"RemoteMobileTimeKey": "1559393127",
"TimeKey": "1559393126",
"RequestId": "761377BE-C936-4987-9096-06D11F70EB49",
"RemoteMobileAppVersion": "18.4.1.388",
"RemoteMobileAppName": "VULCAN-Android-ModulUcznia"
}























jvm jako projekt, a nie cały uonet-request-signer (edited)
jvm-android działał jako libka








2019-10-21 23:18:47.985 8925-8925/io.github.wulkanowy.signer.android.app D/signer: Sign starts...
2019-10-21 23:18:48.929 8925-8925/io.github.wulkanowy.signer.android.app D/signer: Sign ends















instance.load(cert, password) zajmuje 7 sekund













GitHub 







android


jvm co już było, żeby działało wszędzie
jvm, żeby nie kombinować z wersjami tudzież nie robić vendoringu w sdk
jvm





[android] na początku, tak jak robiłeś wcześniej'







keystore.load()









import io.github.wulkanowy.signer.android.signContent
import io.github.wulkanowy.signer.android.getPrivateKeyFromCert
// sign content using PFX certificate and API password
val signed = signContent(password, certificate, content)
// sign content using private key extracted from PFX
val signed = signContent(key, content)
// extract private key from PFX
val privateKey = getPrivateKeyFromCert(password, certificate)// using a once generated private key is about 250x faster
// than using the PFX each time

jvm



















Base64.encodeToString(signature.sign(), Base64.DEFAULT)
damnit. DEFAULT




Unexpected char 0x0a at 76 in RequestSignatureValue value: JdMy6dz0jYe/nblablablablablablaHD+w6Fz5xablablablablablabla2ES+blablablablablabla0cQqrHP
Yxzlp2YSqMmnCbU90blablablablablablaQjwX39vNQjTYniaVGRrvTVl2xSaGf9GT



















GitHub 




password to tak jakby API key, a content to request body







GitHub 































constów

vali
varów ale widzę że się powoli odzwyczaja XD
ThisIsOurHardWorkPleaseDoNotCopyOrSteal(c)2019.KubaSzThisIsOurHardWorkPleaseDoNotCopyOrSteal(c)2020.KubaSz?

let headers = "";
let values = "";
let first = true;
for (let data in signData) {
data = signData[data];
if (data == null)
continue;
if (!first)
headers += " ";
first = false;
headers += data[0];
values += data[1];
}




pleaseStopRightNow


GitHub 









! [remote rejected] hebe -> master (permission denied)
error: failed to push some refs to 'git@github.com:kuba2k2/uonet-request-signer.git'
GitHub 














6dcccdddcc4663760d00c3d3dc01b89da954c0ec przestało działaćRefactor getHeadersList() to działavalues: "api%2fmobile%2fregister%2fhebe,Sun, 27 Jan 2019 23:00:01 GMT"
values: "api%2fmobile%2fregister%2fhebeSun, 27 Jan 2019 23:00:01 GMT" (edited)





[plugin] Loaded /home/mklkj/.config/Insomnia/plugins/@wulkanowy/insomnia-plugin-uonet-request-signer-hebe
[plugin] Loaded /home/mklkj/.config/Insomnia/plugins/insomnia-plugin-headers




headers_poznan czy headers_powiatwulkanowy


Patron: "Święty Wulkan"



















I:\project\ivulcan_node\app.js zamiast .json xd



CertyfikatPfx z Uczen.v3.UczenStart/Certyfikat

let certificate = req.query.certificate

pfx = req.query.pfx

npm i @wulkanowy/uonet-request-signer-node








npm i @wulkanowy/uonet-request-signer-node (edited)
















GitHub 





































































2









{
opensslErrorStack: [
'error:0907B00D:PEM routines:PEM_read_bio_PrivateKey:ASN1 lib',
'error:0D08303A:asn1 encoding routines:asn1_template_noexp_d2i:nested asn1 error',
'error:0D07803A:asn1 encoding routines:asn1_item_embed_d2i:nested asn1 error'
],
library: 'asn1 encoding routines',
function: 'asn1_check_tlen',
reason: 'wrong tag',
code: 'ERR_OSSL_ASN1_WRONG_TAG'
}
BEGIN PRIVATE KEY jest dołączane w signerze
-----BEGIN RSA PRIVATE KEY-----



\\r escapować


BEGIN PRIVATE KEY to coś z PKCS#8BEGIN RSA PRIVATE KEY to RSA (edited)











Windows uses .cer extension for an X.509 certificate. These can be in "binary" (ASN.1 DER), or it can be encoded with Base-64 and have a header and footer applied (PEM); Windows will recognize either.-----BEGIN
































63 ff 6f 5d d5 32 06 59 66 ac d3 97 ee 10 e5 d6 99 c6 5e cd


fingerprint: forge.pki.getPublicKeyFingerprint(cert.publicKey, {
type: 'SubjectPublicKeyInfo',
encoding: 'hex',
}),


92:AE:CC:39:21:B7:19:FE:1C:5B:0D:D7:9C:A4:54:D8:94:77:C3:86
forge.ssh.getPublicKeyFingerprint(key, {encoding: 'hex', delimiter: ':'});

D7:F8:82:39:F4:28:95:48:DE:4B:38:7E:91:D8:93:2F:8E:BB:74:BD$cert = file_get_contents('app_certificate_ca_certificate.cer');
$pkey = file_get_contents('app_certificate_ca_certificate.pkcs8');
$fingerprint = openssl_x509_fingerprint($cert);



C5:E4:DF:ED:DF:5E:63:3C:49:74:74:80:8F:82:0F:54:A3:E9:DF:20

DE:BD:7F:B7:CF:F6:C2:66:1B:67:D7:F1:4D:A8:F3:0E:9B:D0:26:6C

2B:1A:27:18:E4:94:30:94:B8:7F:AB:26:D8:A0:C2:4D:16:2F:F7:75






CN=fake









APP_CERTIFICATE)

namedCurve

GitHub 

GitHub 



npm install @wulkanowy/uonet-request-signer to nie pobiera wszystkich plików? Bo jak sobie sklonuje z githuba z folderu node to jest więcej plików






$ npm i @wulkanowy/uonet-request-signer-node















Security i CommonCrypto chyba tylko macowe jestroot@b1c5c5c953f8:/uonet-request-signer/swift# swiftc PKCS12.swift
PKCS12.swift:9:8: error: no such module 'Security'
import Security
^














xcodebuild clean build (edited)

GitHub 





function signContent(password: String, certificate: String?, content: String)

UonetRequestSigner





GitHub 









exclude w targetach w Package.swift






GitHub 

















VQ8Cag== a tutaj Go+A==, co by sugerowało że jednak zły podpis się generuje





\n byłoby jako dwa znaki wstawione, zamiast rzeczywiście nowej linii
" daje się tylko wtedy, gdy w stringu jest '



















GitHub 

















private_key: PEM-encoded PKCS#7 RSA2048 private key, bo ogólnie to klucz można przedstawić na wieele sposobów (edited)







AppName, AppVersion, CertificateId, Envelope: <tu twój json>, RequestId, Timestamp...

zawinięte body JSONowe, oraz nagłówki potrzebne do wysłania

String? czyli body, oraz jakaś Map<String, String> dla nagłówkówApiRequest<PayloadType>(data...) LUB w interceptorze to wrappować
















































KeyPairGeneratorSpec jest deprecated































































































GitHub 
signature całe pole headers to mówi ze są nieprawidłowe pola, ale jak już dam to error od razu (edited)

headers









Użytkownik nie jest uprawniony do przeglądania żądanych danychapi/mobile/register/new











Użytkownik nie jest uprawniony do przeglądania żądanych danych













MIICyzCCAbOgAwIBAgIBATANBgkqhkiG9w0BAQsFADApMScwJQYDVQQDDB5BUFBfQ0VSVElGSUNBVEUgQ0EgQ2VydGlmaWNhdGUwHhcNMjAxMTEyMjExMzU1WhcNMzAxMTEyMjExMzU1WjApMScwJQYDVQQDDB5BUFBfQ0VSVElGSUNBVEUgQ0EgQ2VydGlmaWNhdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCc8MqjIazn1LowS5PWWz9PsxpPbqPYB+sNvPJu5RIpgepGFZYLdp3aA/ZBpQ5IEi1StogFPZw9w4VWrj5NCqXnNHll973qwUBsgwtV7a0On/kLicaq66Z4y8CwbwOEg9oW39aD/9IC90wDMtjBfv0zDxmhIZKc9suh1NgXp4zr7yvxsu+54hnDVdf1H0+Xe5HDedObwdigRgmqynFWRzELDz2soXnL4WBpfU4xd2ju8Hph1aEoBYaCEtYkg7I/KcC+cpv16IAQRg7tiDzBqe3i58Mx2bQ2fkcvmrR5WIo4xkjMauOO5Zk6a7BmukD6uXPGapDtVx/ze+qLUCcJ9XTfAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAGmwYVm2V52y4a3CnxfdwoaoFjBaJgyO4geYjc74EKhrnsMkWF0tbefDFIOHj00iAo9F8KZ1Zb881lk3QwY7vm8oM580UbZ2Y8/cDl+SvLO4Qxk+cTafWY1cFFd8dk1VE1RICozO8hGBLfoS+hgyQMS9ulgZZM66jlBhOBisO1pMMqAFFQX0VBbAYoV9pHkCdNjRXZ8sgu8KYZEdzAaUyNQ/1Zleqlk8YFNqPY1YuTcmnq9INpqUgGkwMMcrCh1ixumW2XPtSr7lpgBBe6Wib8TdtewzKdcufNY8xmvEb2FHK70Cem5yPByA+PmHxjd/iPkH7N3lADAhj2Zzmekirv8=


{
"Timestamp": 1605208912103,
"AppName": "DzienniczekPlus 2.0",
"Envelope": {
"CertificateType": "X509",
"PIN": _pin__,
"Certificate": "MIICyzCCAbOgAwIBAgIBATANBgkqhkiG9w0BAQUFADApMScwJQYDVQQDDB5BUFBfQ0VSVElGSUNBVEUgQ0EgQ2VydGlmaWNhdGUwHhcNMjAxMTEyMTkyMTUxWhcNMzAxMTEyMTkyMTUxWjApMScwJQYDVQQDDB5BUFBfQ0VSVElGSUNBVEUgQ0EgQ2VydGlmaWNhdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMvkWm0TIebWfCKsX6GKJKANurAMy/Yb/SkK9MHfsaUQMaOs3bopZN7sxzKD4EcgYiZ1F0kpSei1mEpSimo1Bbfa1PfaCZB/XYD2Pe6X71OqAFtt9cB56sY7PIZGT0hu2Vbbn3EbSOudhf+9yAF0HYsBpUgJ3hFd4xDAYZHfy09Ho4aKwnGuVHkuac1bv1bV1q3n9cxX9UimU1qG9HWznzV0Ml++1FeIqVcNRvPlAkVg7KeZQgPrz1eoC+53v5PB71OAfYl2RRft35QIZuqKz4slhT9MsuQtaYw9Duvq9e/sUb1gH1EP4gUzCXkHHsEOyY0OaIvtMGlw6/w39mZukfAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAEvihqczHp1o1rjU1pnMicudAkyOKYw6TOv0p2+bxHIc88F+zt0hz2buE+e6TQJ5opHw2oA12LpP61k7HK+ZyBb5xLuOHww41V1VgCzoudfMsb7apnP2wCr7pKO6OqpVACoqE4udl2bpVH0C8fRItWO72ThcmFrX4zLb2GhGL0jCMGlkcClJKZJ9E0+3CBUl9yxjDYmTjjjf/UrXxr17WfY8vvwdnIcIyJXUkrgyqjPC9/BBiem9VwJhvzJAX6N4h3oxfptTpNajov2v+TKZvVRbaV+u4LokWDA8bp4i3XTyR6TqbSCMM8uwK0Jmubem/DF24TP3Tyet+JRWWMZby4o=",
"OS": "iOS",
"SelfIdentifier": "87aa1a6a-7107-4411-a424-b6e77fe74214",
"CertificateThumbprint": "1eadcde111783128a9ffce55a781cc8cafe23968",
"DeviceModel": "devicemodel",
"SecurityToken": "__token__"
},
"TimestampFormatted": "Thu, 12 Nov 2020 20:21:52 GMT",
"RequestId": "7b95b24b-a5f6-484c-bfaf-c5fba7903176",
"FirebaseToken": "dyTds61iFpU:APA91bF8ZHy89L9Nr1q6rQDLllqSTZ4ryulpiQLMXP0a2SRXfKD6lVl6Y0PBEkFTy60sOyP498vQWPYWqMrKLSm1L_Yqdq8fljg3cwgDtem6vrxHyqhhRR2pEWCtKura09_xB4BNZCNS",
"AppVersion": "1.0",
"API": 1,
"CertificateId": "1eadcde111783128a9ffce55a781cc8cafe23968"
}Host: lekcjaplus.vulcan.net.pl
Digest: SHA-256=WCmYLFyx1f4hpjPo/CMRPzT9F9YV/3qbPoJZ06NzdXo=
Accept: */*
vAPI: 1
Accept-Language: pl-pl
vCanonicalUrl: api%2Fmobile%2Fregister%2Fnew
Signature: keyId="1eadcde111783128a9ffce55a781cc8cafe23968",algorithm="sha256withrsa",signature=Base64(SHA256withRSA(N3MscHKiGIAtHgF0N85ba1dXOpn4G0T9bhYEN6ysc0Ni/E8ko3TdT2DvgFvBza25v561wh5BY34QTR47DWKWjCoj9RbSoGhObyPeZfDkiVdGOuJr8qmqg59BG89jtZMid4Oqfa4vdgEizgF3MFEF1aeB78eHp3RLxKnw/7lpxUG7c9uzubhJ/G9IYAC70o8DiULx9fxDk5bKAtWNEvWlWfaba2n5STnLYZ+95S6jAHXdjTlGIWFYoYBXGtaUIR1xeKAgoPwbdb+mP5FBlIzYMM+Nx1gXU2RJxLzBWPhNBPjJktYgYcR1JIBxNFlQ/z+3WGJaz+TXuq2l6pnDWW/CPg==)),headers="vCanonicalUrl Digest vDate"
Accept-Encoding: gzip, deflate, br
vOS: iOS
vDate: Thu, 12 Nov 2020 19:21:52 GMT
vDeviceModel: devicemodel
User-Agent: okhttp/3.11.0
Content-Length: 1644
Connection: keep-alive
Content-Type: application/json
Pragma: no-cache
Cache-Control: no-cache
_pin__ zamiast __pin__
123456 wpisalem _pin___








Android po prostu

Timestamp jako teraz w milisekundach, TimestampFormatted jako teraz w stringu i vDate jako formatted teraz - 1 godzina (edited)





{"EnvelopeType":"Object","Envelope":null,"Status":{"Code":100,"Message":"Użytkownik nie jest uprawniony do przeglądania żądanych danych: YXBpJTI0UkdqMXV0Tm9GbVNaYVdDbkFPMHNvYXQ1bmI5Yjd4eExNYm9PMHEvS3pzPVRodSwgMTIgTm92IDIwMjAgMjE6MzA6MzQgR01U"},"RequestId":"2beedadd-48cd-4581-9b31-eb8abe4545ae","Timestamp":1605216635137,"TimestampFormatted":"2020-11-12 22:30:35","InResponseTo":null}

kontakt@vulcan.net.plnoreply@vulcan.net.pl








Internal server error











Digest z headerow to CC_SHA256 z body requestu
Signature w headerach to .rsaSignatureMessagePKCS1v15SHA256 wartosci wybranych headerow

DigestSHA-256=xxx, gdzie xxx to digestSignature, co jest czymś w stylu keyId="fingerprint",headers="costam costam"...Digest: SHA-256=WCmYLFyx1f4hpjPo/CMRPzT9F9YV/3qbPoJZ06NzdXo=Signature: keyId="1eadcde111783128a9ffce55a781cc8cafe23968",algorithm="sha256withrsa",signature=Base64(SHA256withRSA(N3MscHKiGIAtHgF0N85ba1dXOpn4G0T9bhYEN6ysc0Ni/E8ko3TdT2DvgFvBza25v561wh5BY34QTR47DWKWjCoj9RbSoGhObyPeZfDkiVdGOuJr8qmqg59BG89jtZMid4Oqfa4vdgEizgF3MFEF1aeB78eHp3RLxKnw/7lpxUG7c9uzubhJ/G9IYAC70o8DiULx9fxDk5bKAtWNEvWlWfaba2n5STnLYZ+95S6jAHXdjTlGIWFYoYBXGtaUIR1xeKAgoPwbdb+mP5FBlIzYMM+Nx1gXU2RJxLzBWPhNBPjJktYgYcR1JIBxNFlQ/z+3WGJaz+TXuq2l6pnDWW/CPg==)),headers="vCanonicalUrl Digest vDate"Digest i Signature




























su1b6w04yLdKYRSNAKOMXIPGpoN8w9f6roXCXibE826BXY5ZN2z9JQe9xayIM4i2hVtjtcggaxHVRxfKUtCjCvg/g5SOAg9bRmkJjiJLh5uCf5DuWzXrnc6D1ILEj6vJwoUi/vd4AGMKlfz7T3fCNm/qXjYH7NyWhuzmW/GMKww7Aa83kqx3eF0cw4Yu+LOiPqpoYBwG6+7vaVpra6FD0QUT23JiHtiyqKUhTyM9kNY96AOknW5jys10nLPNoNCbfgpWVXF21mG8ePDtEV7qDj6TXBG6fRiUcOR+qSE8EUBkuvPlGwHHtQaqj9dgm6iWF1lOySC7cOyKjorbz8teAQ== (edited)rsaSignatureMessagePKCS1v15SHA256

"{}".data(using: .utf8)



















getSignature



function getSignatureValue(values, pkey) {
return createSign('RSA-SHA256')
.update(values)
.sign("-----BEGIN PRIVATE KEY-----\n" + pkey + "\n-----END PRIVATE KEY-----", "base64");
} (edited)
def get_signature_values(fingerprint, private_key, body, full_url, timestamp):
canonical_url = get_encoded_path(full_url)
digest = get_digest(body)
headers, values = get_headers_list(body, digest, canonical_url, timestamp)
signature = get_signature(values, private_key)
return (
"SHA-256={}".format(digest) if digest else None,
canonical_url,
'keyId="{}",headers="{}",algorithm="sha256withrsa",signature=Base64(SHA256withRSA({}))'.format(
fingerprint, headers, signature
),
)signature = get_signature(body, private_key)




















hebe app.
GitHub 







GitHub 





GitHub 












GitHub 










GitHub 




















GitHub 
























CertificateThumbprint jeśli nie ma certyfikatu?



strings by coś mogło pokazać















signData["vDate"] = timestamp.format(DateTimeFormatter.RFC_1123_DATE_TIME) // ZonedDateTime
signData["vDate"] = SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z", Locale.ROOT).apply { // Date
timeZone = TimeZone.getTimeZone("GMT")
}.format(timestamp) (edited)







GitHub 



certificateHash zwracane przez generateCertificate()?


certificateHash zwracane przez generateCertificate()? publicHash














GitHub 







Failed to build test:test:
../../.pub-cache/hosted/pub.dartlang.org/analyzer-0.41.2/lib/src/error/best_practices_verifier.dart:258:50: Error: The property 'displayString' is defined in multiple extensions for 'TargetKind' and neither is more specific.
- 'TargetKind' is from 'package:meta/meta_meta.dart' ('../../.pub-cache/hosted/pub.dartlang.org/meta-1.7.0/lib/meta_meta.dart').
Try using an explicit extension application of the wanted extension or hiding unwanted extensions from scope.
var kindNames = kinds.map((kind) => kind.displayString).toList()
^^^^^^^^^^^^^
../../.pub-cache/hosted/pub.dartlang.org/analyzer-0.41.2/lib/src/error/best_practices_verifier.dart:1950:14: Context: This is one of the extension members.
String get displayString {
^^^^^^^^^^^^^
../../.pub-cache/hosted/pub.dartlang.org/meta-1.7.0/lib/meta_meta.dart:91:14: Context: This is one of the extension members.
String get displayString {
^^^^^^^^^^^^^
../../.pub-cache/hosted/pub.dartlang.org/analyzer-0.41.2/lib/src/error/best_practices_verifier.dart:260:36: Error: The getter 'commaSeparatedWithOr' isn't defined for the class 'List<dynamic>'.
- 'List' is from 'dart:core'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'commaSeparatedWithOr'.
var validKinds = kindNames.commaSeparatedWithOr;
^^^^^^^^^^^^^^^^^^^^
Exited with code exit status 1












var formattedTimestamp = timestamp.ToString("R");








hebe-jvm, ale coś tam się zepsuło z jitpackiem, wkurzyłem się i idąc za ciosem zestawiłem config tak, żeby się tam budowała i wrzucała .jar do sonatype, na razie tylko jako snapshot



io.github.wulkanowy.signer:hebe-jvm:0.1.0-SNAPSHOTrepositories {
maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
}









