Codesigning SWF? - actionscript

AIR allows to inject code using Loader.LoadBytes()
this allows to download remote plugins as swf files which will have full access to everything that the AIR application has access to. This imposes a security risk, so it would be desirable to digitally sign the swf's.
What's the best way to do this and to verify the code signature?
I know the as3corelib has some encryption functionality and also for X.509 certificate - but I didn't find a ressource explaining how to use it. Also, maybe there's some 'official' way to codesign SWF's?

One robust method is using public key encryption, which goes something like this:
You will need an asymmetric encryption algorithm (eg, RSA), and a hash algorithm (eg, SHA, MD5).
Generate a public-private key pair.
Generate and checksum of the data using the hash algorithm.
Encrypt the checksum with the private key using the encryption algorithm. This becomes the "signature".
Send the data to the client along with the signature.
Decrypt the signature on the client with the public key to obtain the original checksum.
Generate a checksum from the data on the client.
Compare the checksums. If they match, then you know that the data came from you without alterations. If they do not match then you know the data was altered after it was sent from you, or it came from someone else.
See http://en.wikipedia.org/wiki/Public-key_cryptography
An attacker can bypass this security if they are able to intercept the connection and modify the original client SWF file and either change the public key, or remove the security mechanism entirely. Use TLS or SSL to prevent attackers intercepting the data.
An x.509 certificate is little more than a public key bundled with some meta-data. The standard also specifies a mechanism for validating the certificate, by relying on a certificate authority (CA) (see http://en.wikipedia.org/wiki/X.509).
The AS3Crypto library provides (amongst other things), an implementation of RSA, MD5, and an x.509 parser (see http://code.google.com/p/as3crypto/).
Here is some code. The signing process entails computing the hash of the data, then signing it with the private key to produce a signature, eg:
var rsa:RSAKey;
var md5:MD5;
var data:ByteArray = getSWFBytes();
var signature:ByteArray = new ByteArray();
var originalHash:ByteArray;
// read private key
rsa = PEM.readRSAPrivateKey(private_key);
// create the checksum of the original data
md5 = new MD5();
originalHash = md5.hash(original);
// encrypt the data using the private key
rsa.sign(data, signature, original.length);
The data and signature are sent to the client. The client decrypts the signature using the public key stored in the cert and compare it to the computed hash of the data, eg:
var rsa:RSAKey;
var md5:MD5;
var data:ByteArray = getSWFBytes();
var signature:ByteArray = new ByteArray();
var decryptedHash:ByteArray = new ByteArray();
var clientHash:ByteArray;
// load the certificate
var cert:X509Certificate = new X509Certificate(public_cert);
// get the public key from the cert
rsa = cert.getPublicKey();
// decrypt the signature with the public key
rsa.verify(signature, decryptedHash, encrypted.length);
// create a hash of the data
md5 = new MD5();
clientHash = md5.hash(data);
// compare the hashes
// isEqual compares the bytes in the input byte arrays, it returns true only of all bytes in both arrays match
if (isEqual(clientHash, decryptedHash))
trace("signature valid");
else
trace("signature invalid")
You can check if the certificate is signed like this:
var store:X509CertificateCollection = new MozillaRootCertificates();
var cert:X509Certificate = new X509Certificate(public_cert);
var isValid:Boolean = cert.isSigned(store, store);
You can load the raw SWF bytes like this:
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, completeHandler);
loader.load(new URLRequest(url_of_swf_to_load));
Example x.509 private key (usually created when you apply for a certificate):
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQDoKlLzpJeLcoPYQQYPa0diM4zpZ+0rKeRxhx9ssq91DzwAeSmM
7wT03WLiLZkqPt2MS3uNo75zK5RtmjHqF6Ojfs2tbSdlCK5tpisvOAssuq0o5vIz
g/MhS2PIijnBtVB9XFSTXxhveKeIq1VgdB2wHW95+zhBF+Z1hsYcNRRFFwIDAQAB
AoGAI8wK2EhjmXvBuoFkJtJ6wjiCnKaKmiIueBbGkKMIjLsZnFUSRAnCsOLF0WwI
dswUqwIkfdVmkymADFo/IgIdF9hLGNLRskIPKGZWEUC8d5ZJnRg+nuzi2c2msN5u
/BvCCgL5/shBhO5KvrPbU/Fbs/k4saCDQZ2EO4HpueRZWGkCQQD6hC0pTfyW4yQT
Qr/dY7FhOwdOh/8ewGyXBa9ruOuZqTR23Ya20O8NuF22+NqW9AZl7uioiTZyZkOV
jqAckelrAkEA7T9QVdK+QcaQSznrZPJpXlSIDLSBRWjaPKBoypnNTF3y3JkUQE0L
iA0c2oUc8D+LCgx9vA0Ai0IzwzrIec+iBQJAJb5YV4rKbalXPBeodKCajv2nwis3
QtjXA4H1xhMcXBBkOSxzKYQdIEIQzIp91JR7ikwOfaX+sAm8UQImGWfadQJAMAb4
KVePQluDDGd+OqJEKF9uZzwHS1jNjSZf8FuwTrxaFMQ8cEPoiLM22xnFYPFMIU2k
CnSLXqWZOvVkbhxVTQJAL3xIc5AUbhsEp7ZeeJrkPRv5rCObmLw0+wIaERtMX83b
PNM0TpzY6EXk+geTCqudAipYF/A7qn38wpOh+PuuVg==
-----END RSA PRIVATE KEY-----
Example cert:
-----BEGIN CERTIFICATE-----
MIID4zCCA0ygAwIBAgIJAL7k5X3sCvniMA0GCSqGSIb3DQEBBQUAMIGoMQswCQYD
VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEBxMIU2FuIEpvc2Ux
FDASBgNVBAoTC2h1cmxhbnQuY29tMRcwFQYDVQQLEw5hczMgY3J5cHRvIGxpYjEY
MBYGA1UEAxMPSGVucmkgVG9yZ2VtYW5lMSgwJgYJKoZIhvcNAQkBFhloZW5yaV90
b3JnZW1hbmVAeWFob28uY29tMB4XDTA3MTEwNTA1MjUyOVoXDTA4MTEwNDA1MjUy
OVowgagxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMREwDwYDVQQH
EwhTYW4gSm9zZTEUMBIGA1UEChMLaHVybGFudC5jb20xFzAVBgNVBAsTDmFzMyBj
cnlwdG8gbGliMRgwFgYDVQQDEw9IZW5yaSBUb3JnZW1hbmUxKDAmBgkqhkiG9w0B
CQEWGWhlbnJpX3RvcmdlbWFuZUB5YWhvby5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD
gY0AMIGJAoGBAOgqUvOkl4tyg9hBBg9rR2IzjOln7Ssp5HGHH2yyr3UPPAB5KYzv
BPTdYuItmSo+3YxLe42jvnMrlG2aMeoXo6N+za1tJ2UIrm2mKy84Cyy6rSjm8jOD
8yFLY8iKOcG1UH1cVJNfGG94p4irVWB0HbAdb3n7OEEX5nWGxhw1FEUXAgMBAAGj
ggERMIIBDTAdBgNVHQ4EFgQU/XyNp2QghYm3MWOU5YoUoFWcTKMwgd0GA1UdIwSB
1TCB0oAU/XyNp2QghYm3MWOU5YoUoFWcTKOhga6kgaswgagxCzAJBgNVBAYTAlVT
MRMwEQYDVQQIEwpDYWxpZm9ybmlhMREwDwYDVQQHEwhTYW4gSm9zZTEUMBIGA1UE
ChMLaHVybGFudC5jb20xFzAVBgNVBAsTDmFzMyBjcnlwdG8gbGliMRgwFgYDVQQD
Ew9IZW5yaSBUb3JnZW1hbmUxKDAmBgkqhkiG9w0BCQEWGWhlbnJpX3RvcmdlbWFu
ZUB5YWhvby5jb22CCQC+5OV97Ar54jAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEB
BQUAA4GBABsXUJjiRAz+FeiVq4JMSBWeiiGcXTw+8sNv8SfWaWx3su+AgooKlBn3
nsGKf3BEDdmJCOSgY0+A5Pce9SRoAMhabHKwoLEogrtp2p8vRj2OTMjWBW7ylrxj
FvUpFdc8qFaqTtgH6+JiIYllGFlcsSV+6d9fDPaFDZEHjz5GweWJ
-----END CERTIFICATE-----
Both examples were taken from as3crypto.

Related

ECIES encryption and EC key generation in Swift

Backend uses this java implementation for encrypting the data using public key(generated from iOS App in swift),
Cipher iesCipher = Cipher.getInstance("ECIESwithAES-CBC");
byte[] derivation = Hex.decode(derivationString);
byte[] encoding = Hex.decode(encodingString);
byte[] nonce = Hex.decode(nonceString);
IESParameterSpec params = new IESParameterSpec(derivation, encoding, 128, 128, nonce, true);
iesCipher.init(Cipher.ENCRYPT_MODE, publicKey, params);
byte[] ciphertext = iesCipher.doFinal(data.getBytes());
But in swift I could not find any equivalent library to decrypt it. I am using the SwiftECC for generating the EC key-pair and sending the public key to server. Then server encrypts the data using that public key as mentioned in above implementation code. But SwiftECC has no any decrypt function which accepts the arguments like derivation, encoding, nonce. And I could not find anything similar to above java implementation in swift.
ECIES is using ephemeral static-ECDH + key derivation + encryption, where the public key of the ephemeral key pair is stored with the ciphertext. So if you find ECDH + the right key derivation + AES-CBC encryption (probably using PKCS#7 padding) then you'd be in business. Apparently BC uses KDF2 with SHA-1 for key derivation. I've asked and answered what KDF2 is here.
I’ve implemented ECIES in EllipticCurveKit, feel free to use it as inspiration. Should be straightening enough to port it to SwiftECC if you don’t want to use EllipticCurveKits EC implementation.
I've hard coded the curve to be Secp256k1 (aka "the bitcoin curve"), but you could easily make it generic, by passing in a generic Curve type, just change:
func seal<Plaintext>(
_ message: Plaintext,
whitePublicKey: PublicKey<Secp256k1>,
blackPrivateKey: PrivateKey<Secp256k1>,
nonce: SealedBox.Nonce? = nil
) -> Result<SealedBox, EncryptionError> where Plaintext: DataProtocol
into (which should work in EllipticCurveKit, and should be possible in other EC libs too):
func seal<Plaintext, Curve>(
_ message: Plaintext,
whitePublicKey: PublicKey<Curve>,
blackPrivateKey: PrivateKey<Curve>,
nonce: SealedBox.Nonce? = nil
) -> Result<SealedBox, EncryptionError> where Plaintext: DataProtocol, Curve: EllipticCurve

How can I do public key pinning in Flutter?

I want to the pin the public key of my server so that any request made to the server has to have that public key (this is to prevent proxies like Charles sniffing the data).
I had done something similar in Android with Volley.
How can I do the same with Flutter?
Create your client with a SecurityContext with no trusted roots to force the bad certificate callback, even for a good certificate.
SecurityContext(withTrustedRoots: false);
In the bad certificate callback, parse the DER encoded certificate using the asn1lib package. For example:
ASN1Parser p = ASN1Parser(der);
ASN1Sequence signedCert = p.nextObject() as ASN1Sequence;
ASN1Sequence cert = signedCert.elements[0] as ASN1Sequence;
ASN1Sequence pubKeyElement = cert.elements[6] as ASN1Sequence;
ASN1BitString pubKeyBits = pubKeyElement.elements[1] as ASN1BitString;
List<int> encodedPubKey = pubKeyBits.stringValue;
// could stop here and compare the encoded key parts, or...
// parse them into their modulus/exponent parts, and test those
// (assumes RSA public key)
ASN1Parser rsaParser = ASN1Parser(encodedPubKey);
ASN1Sequence keySeq = rsaParser.nextObject() as ASN1Sequence;
ASN1Integer modulus = keySeq.elements[0] as ASN1Integer;
ASN1Integer exponent = keySeq.elements[1] as ASN1Integer;
print(modulus.valueAsBigInteger);
print(exponent);
Key rotation reduces risk. When an attacker obtains an old server hard drive or backup file and gets an old server private key from it, they cannot impersonate the current server if the key has been rotated. Therefore always generate a new key when updating certificates. Configure the client to trust the old key and the new key. Wait for your users to update to the new version of the client. Then deploy the new key to your servers. Then you can remove the old key from the client.
Server key pinning is only needed if you're not rotating keys. That's bad security practice.
You should do certificate pinning with rotation. I have added example code in How to do SSL pinning via self generated signed certificates in flutter?

Load and use PKCS#8 Private Key

I am currently generating and saving a key pair of RSA keys inside a Java REST Server using the following block of code:
keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
KeyPair keyPair = keyPairGenerator.genKeyPair();
publicKey=keyPair.getPublic();
publicKeyBase64 = Base64.encodeBase64String(publicKey.getEncoded()) ;
PrivateKey privateKey = keyPair.getPrivate();
privateKeyBase64 = Base64.encodeBase64String(privateKey.getEncoded());
Now I want to use this same private key to decrypt another information returned from the server using an iOS client. As far as I know, the iOS does not provide great native support for RSA encryption. How can I decrypt information using this private key, supposing that I currently have the key encoded as a PKCS#8 Base64 string (like inside the variable privateKeyBase64)?
Thank you!

Apple Pay - decrypt payment data

I am trying to decrypt paymentData property of PKPaymentToken object upon a successful Apple Pay authorization.
I am trying to follow the instruction here, but I am stuck on step 2 of the decryption steps, which says:
Use the value of the publicKeyHash key to determine which merchant
public key was used by Apple, and then retrieve the corresponding
merchant public key certificate and private key.
How do I do that?
Please advise.
Thanks!
Here's how to compute the publicKeyHash in Ruby, given the Apple Pay certificate file downloaded from the Apple Developer Center.
require "base64"
require "digest"
require "openssl"
# set cert_file = path to the downloaded Apple Pay .cer file
cert = OpenSSL::X509::Certificate.new(File.read(cert_file))
# strip off the "-----BEGIN PUBLIC KEY-----" line at the start of the string
pem = cert.public_key.to_pem.split("\n").drop(1)
# strip off the "-----END PUBLIC KEY-----" line at the end of the string
pem = pem.take(pem.length - 1)
decoded = Base64.decode64(pem.join)
public_key_hash = Digest::SHA256.base64digest(decoded)
The value of the publicKeyHash field is...a hash of your public key. As per the documentation, it's a SHA-256 hash of the X.509 encoded public key bytes of the merchant's certificate. You use this to determine which merchant identifier was used to sign the payment data (you probably only have one merchant identifier, in which case you'll already know which one is being used).

Encrypt/Decrypt text using existing key pair

This has been extremely confusing to me. I have a process where I generate a public/private key pair using PHP. This is the code where I do that:
$config = array(
"digest_alg" => "sha512",
"private_key_bits" => 4096,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
);
// Create the private and public key
$res = openssl_pkey_new($config);
And here is an example of the generated output:
-----BEGIN PUBLIC KEY----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1ufdaaaDQuWPuBlw8Vce
WeGwdL3KhrC/YzgWi8oP72bQ2ZzgxzNcXHdmWGfXax4EBlWwIPBbTSNboi6urieb
bPNIS/ei/AjGBKO/yJ2iDkfnxmy6xBxwpunqeq2TjEDDNXb2Y0g896gIjfwN8FZk
olLspoFks5ipAxdYLNlWR5stgxWeEXC2gpAPLaP00d3Xg/Qhsm2fUBvlJHQReiS1
Mwyajg0EV72U3YpP0OK19z0YLBFRhaUbnE+Mx6TSnB9XqaWe4GKsBNSO06Lz4N9j
k7Sg16DXpueKHo8pDZwuN2qbIG3fGc3ibNMR2U6lux218BGTIgGdvoAar1E3cOF1
VmLI3aDS/EVejzDs3gkG1rxcrbCFajnWe5Yl1J+nXefFBedr2FLx6ChSPZFV1x3P
DUmR1hb/NDsLHwnj7qQqqhtgfPdFql4EjGFGUvYgid1K0u/8B6Vqk0k9JKU5nrN5
d1e3H7qJm/kbBoHNsI/0gbuUyRKTIpxU5b9ex51WpA80FBMC/Ao6DeWLNu59W134
YGu5kfI1qFI0w5xUsA3IU91Ak2tHYEzzjnIz0rVMoJezLbtxcv26e5gMDjuQN//d
UM/Qe6Akck382yYgdrivgUjxB3A/IWP5IhKaLZazAWxgrc6EPvcbQFgzU/T5EbHI
dt279SgTgQ+OlotfvnKNmL0CAwEAAQ== -----END PUBLIC KEY-----
And private key:
-----BEGIN RSA PRIVATE KEY----- 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 -----END
RSA PRIVATE KEY-----
So I save these two files to my server where I am storing my keys. When my app runs, it receives the appropriate public/private keys just like this, in this format, in text format. Here is my question: How do I use these existing keys, based upon the algorithm (SHA512, 4096 bits) in a function to both encrypt and decrypt NSStrings? To my understanding, I have to do some work with the keys before I can use them with iOS - strip headers, convert to base64, eg?
In short, I am looking to create two functions. One that can decrypt and one that can decrypt - both should take the certificates in text format above (or converted to something else) as well as the text to be encrypted and return the encrypted/decrypted version.
You aren't using SHA512 for the encryption/decryption, that value is used if you are then going to create a certificate or certificate request tied to this keypair.
Here is a breakdown on the parameters you used:
"digest_alg" => "sha512"
For the digest in a certificate.
"private_key_bits" => 4096,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
This means you generated an RSA-4096 key pair. So make sure to encrypt/decrypt using RSA-4096.
While this library doesn't address my original needs, it's security is more than enough for my requirements. It easily adds encrypting/decrypting across multiple languages as well.
https://github.com/RNCryptor/RNCryptor

Resources