-
Notifications
You must be signed in to change notification settings - Fork 38
Merge #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Ponyboy2024
wants to merge
12
commits into
meixler:master
Choose a base branch
from
Ponyboy2024:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Merge #5
Changes from 1 commit
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
e9ffdcb
Add files via upload
Ponyboy2024 33eca3f
Create generator-generic-ossf-slsa3-publish.yml
Ponyboy2024 b856d16
Create jekyll-docker.yml
Ponyboy2024 a18a312
Merge pull request #1 from Ponyboy2024/Jekyll-1
Ponyboy2024 c312129
Add files via upload
Ponyboy2024 1a4cd35
Merge pull request #2 from Ponyboy2024/Web-encryption
Ponyboy2024 a0f16b7
Add files via upload
Ponyboy2024 84335a1
Delete python-package.yml.txt
Ponyboy2024 82a633e
Add files via upload
Ponyboy2024 64e8788
Merge pull request #3 from Ponyboy2024/Web-browser.1.2
Ponyboy2024 7dcd273
Rename README.md to Mmsave.file.md
Ponyboy2024 6dde9ca
README.md
Ponyboy2024 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Ponyboy2024 marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,56 +1,114 @@ | ||
# Web Browser Based File Encryption / Decryption | ||
# Save action | ||
|
||
Use your web browser to encrypt and decrypt files. | ||
The save action saves a cache. It works similarly to the `cache` action except that it doesn't first do a restore. This action provides granular ability to save a cache without having to restore it, or to do a save at any stage of the workflow job -- not only in post phase. | ||
|
||
## Usage | ||
## Documentation | ||
|
||
Download [web-browser-based-file-encryption-decryption.html](https://github.com/meixler/web-browser-based-file-encryption-decryption/blob/master/web-browser-based-file-encryption-decryption.html), then open the .html document in your web browser. Or, simply point your web browser to the .html document hosted [here](https://www.meixler-tech.com/web-browser-based-file-encryption-decryption.html). | ||
### Inputs | ||
|
||
Then, use the web page rendered in your browser to encrypt a file using a password. Use the same password later to decrypt the file. IMPORTANT: The same password that was used to encrypt the file must be used to decrypt the file later. If you loose or forget the password, it cannot be recovered! | ||
* `key` - An explicit key for a cache entry. See [creating a cache key](../README.md#creating-a-cache-key). | ||
* `path` - A list of files, directories, and wildcard patterns to cache. See [`@actions/glob`](https://github.com/actions/toolkit/tree/main/packages/glob) for supported patterns. | ||
* `upload-chunk-size` - The chunk size used to split up large files during upload, in bytes | ||
|
||
## Operation and privacy | ||
### Outputs | ||
|
||
The page uses javascript running within your web browser to encrypt and decrypt files client-side, in-browser. The page makes no network connections during this process, to ensure that your files and password do not leave your web browser during the process. This can be independently verified by reviewing the source code for the page, or by monitoring your web browser's [networking activity](https://developer.mozilla.org/en-US/docs/Tools/Network_Monitor) during operation of the page. The page can also be downloaded and run locally on your system offline. | ||
This action has no outputs. | ||
|
||
## Cryptography | ||
## Use cases | ||
|
||
All client-side cryptography is implemented using the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API). Files are encrypted using AES-CBC 256-bit symmetric encryption. The encryption key is derived from the password and a random salt using PBKDF2 derivation with 10000 iterations of SHA256 hashing. | ||
|
||
### Only save cache | ||
|
||
## Compatibility with openssl | ||
If you are using separate jobs for generating common artifacts and sharing them across jobs, this action will take care of your cache saving needs. | ||
|
||
The encryption used by the page is compatible with [openssl](https://www.openssl.org/docs/man1.1.1/man1/openssl-enc.html). | ||
```yaml | ||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
Files encrypted using the page can be decrypted using openssl using the following command: | ||
|
||
openssl aes-256-cbc -d -salt -pbkdf2 -iter 10000 -in encryptedfilename -out plaintextfilename | ||
- name: Install Dependencies | ||
run: /install.sh | ||
|
||
Files encrypted using the following openssl command can be decrypted using the page: | ||
- name: Build artifacts | ||
run: /build.sh | ||
|
||
openssl aes-256-cbc -e -salt -pbkdf2 -iter 10000 -in plaintextfilename -out encryptedfilename | ||
- uses: actions/cache/save@v4 | ||
id: cache | ||
with: | ||
path: path/to/dependencies | ||
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }} | ||
``` | ||
|
||
## Running the page offline | ||
### Re-evaluate cache key while saving | ||
|
||
The web page is self-contained. The page does not require any supporting files; all javascript and css for the page is contained in the source code of the page. | ||
To run the page locally on your system offline, simply save the page to your system as a .html file, then open the file from your system in your web browser (optionally with networking disabled). | ||
With this save action, the key can now be re-evaluated while executing the action. This helps in cases where lockfiles are generated during the build. | ||
|
||
## Verifying the integrity of the page | ||
Let's say we have a restore step that computes a key at runtime. | ||
|
||
The expected SHA256 checksum hash of the .html file containing the page is: | ||
#### Restore a cache | ||
|
||
c7398059dffd25fa8a9d81c570250887fba61dc4eafcfca42f9081196389ed05 | ||
```yaml | ||
uses: actions/cache/restore@v4 | ||
id: restore-cache | ||
with: | ||
key: cache-${{ hashFiles('**/lockfiles') }} | ||
``` | ||
|
||
If loading the page from a web server, you can verify that the checksum hash of the .html file downloaded from the web server matches the expected checksum hash using the [Page Integrity browser extension](https://www.pageintegrity.net/). | ||
If running the page offline, it is recommended that you verify that the checksum hash of the .html file matches the expected checksum hash before opening the file in your web browser. | ||
#### Case 1 - Where a user would want to reuse the key as it is | ||
```yaml | ||
uses: actions/cache/save@v4 | ||
with: | ||
key: ${{ steps.restore-cache.outputs.cache-primary-key }} | ||
``` | ||
|
||
## Contributing | ||
#### Case 2 - Where the user would want to re-evaluate the key | ||
|
||
Pull requests are welcome. | ||
```yaml | ||
uses: actions/cache/save@v4 | ||
with: | ||
key: npm-cache-${{hashfiles(package-lock.json)}} | ||
``` | ||
|
||
## License | ||
### Always save cache | ||
|
||
This project is licensed under the [GPL-3.0](https://www.gnu.org/licenses/gpl-3.0.en.html) open source license. | ||
There are instances where some flaky test cases would fail the entire workflow and users would get frustrated because the builds would run for hours and the cache couldn't be saved as the workflow failed in between. | ||
For such use-cases, users now have the ability to use the `actions/cache/save` action to save the cache by using an [`always()`](https://docs.github.com/actions/writing-workflows/choosing-what-your-workflow-does/expressions#always) condition. | ||
This way the cache will always be saved if generated, or a warning will be generated that nothing is found on the cache path. Users can also use the `if` condition to only execute the `actions/cache/save` action depending on the output of previous steps. This way they get more control of when to save the cache. | ||
|
||
## Contact | ||
To avoid saving a cache that already exists, the `cache-hit` output from a restore step should be checked. | ||
|
||
Please [contact MTI](https://www.meixler-tech.com/contact.php) for any questions or comments concerning this project. | ||
The `cache-primary-key` output from the restore step should also be used to ensure | ||
the cache key does not change during the build if it's calculated based on file contents. | ||
|
||
```yaml | ||
name: Always Caching Primes | ||
|
||
on: push | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- name: Restore cached Primes | ||
id: cache-primes-restore | ||
uses: actions/cache/restore@v4 | ||
with: | ||
key: ${{ runner.os }}-primes | ||
path: | | ||
path/to/dependencies | ||
some/other/dependencies | ||
|
||
# Intermediate workflow steps | ||
|
||
- name: Always Save Primes | ||
id: cache-primes-save | ||
if: always() && steps.cache-primes-restore.outputs.cache-hit != 'true' | ||
uses: actions/cache/save@v4 | ||
with: | ||
key: ${{ steps.cache-primes-restore.outputs.cache-primary-key }} | ||
path: | | ||
path/to/dependencies | ||
some/other/dependencies | ||
``` |
Ponyboy2024 marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
# -*- coding: utf-8 -*- | ||
## Copyright (c) 2014, Fundación Dr. Manuel Sadosky. Todos los derechos reservados. | ||
## | ||
## La redistribución y el uso en las formas de código fuente y binario, con o sin | ||
## modificaciones, están permitidos siempre que se cumplan las siguientes condiciones: | ||
## | ||
## 1. Las redistribuciones del código fuente deben conservar el aviso de copyright | ||
## anterior, esta lista de condiciones y el siguiente descargo de responsabilidad. | ||
## | ||
## 2. Las redistribuciones en formato binario deben reproducir el aviso de copyright | ||
## anterior, esta lista de condiciones y la siguiente renuncia en la documentación | ||
## y/u otros materiales suministrados con la distribución. | ||
## | ||
## ESTE SOFTWARE SE SUMINISTRA POR LA Fundación Dr. Manuel Sadosky ''COMO ESTÁ'' Y CUALQUIER | ||
## GARANTÍA EXPRESA O IMPLÍCITAS, INCLUYENDO, PERO NO LIMITADO A, LAS GARANTÍAS | ||
## IMPLÍCITAS DE COMERCIALIZACIÓN Y APTITUD PARA UN PROPÓSITO DETERMINADO SON | ||
## RECHAZADAS. EN NINGÚN CASO Fundación Dr. Manuel Sadosky SERÁ RESPONSABLE POR NINGÚN | ||
## DAÑO DIRECTO, INDIRECTO, INCIDENTAL, ESPECIAL, EJEMPLAR O CONSECUENTE (INCLUYENDO, | ||
## PERO NO LIMITADO A, LA ADQUISICIÓN DE BIENES O SERVICIOS; LA PÉRDIDA DE USO, DE | ||
## DATOS O DE BENEFICIOS; O INTERRUPCIÓN DE LA ACTIVIDAD EMPRESARIAL) O POR | ||
## CUALQUIER TEORÍA DE RESPONSABILIDAD, YA SEA POR CONTRATO, RESPONSABILIDAD ESTRICTA | ||
## O AGRAVIO (INCLUYENDO NEGLIGENCIA O CUALQUIER OTRA CAUSA) QUE SURJA DE CUALQUIER | ||
## MANERA DEL USO DE ESTE SOFTWARE, INCLUSO SI SE HA ADVERTIDO DE LA POSIBILIDAD DE | ||
## TALES DAÑOS. | ||
## | ||
## Las opiniones y conclusiones contenidas en el software y la documentación son las | ||
## de los autores y no deben interpretarse como la representación de las políticas | ||
## oficiales, ya sea expresa o implícita, de Fundación Dr. Manuel Sadosky . | ||
## | ||
## Decifrado de imagenes de Snapchat version 5.0.34.10 | ||
## Author: Joaquín Rinaudo | ||
## | ||
|
||
import subprocess | ||
import shlex | ||
import md5 | ||
from hashlib import md5 | ||
from Crypto.Cipher import AES | ||
from Crypto import Random | ||
import json | ||
import time | ||
import os | ||
import base64 | ||
import re | ||
|
||
def run_get_output(command): | ||
try: | ||
return subprocess.check_output(shlex.split(command),stderr=subprocess.STDOUT) | ||
except subprocess.CalledProcessError as grepexc: | ||
return grepexc.output | ||
|
||
def run_blocking_cmd(command): | ||
return subprocess.call(shlex.split(command),stdout=subprocess.PIPE,stderr=subprocess.PIPE) | ||
|
||
def get_android_id(): | ||
try: | ||
android_id = run_get_output(''' adb shell content query --uri content://settings/secure --projection name:value --where "name=\\'android_id\\'" ''') | ||
p = re.compile('Row: 0 name=android_id, value=(.*)') | ||
android_id = p.findall(android_id)[0].strip() | ||
except: | ||
android_id = run_get_output(''' adb shell settings get secure android_id ''').strip() | ||
print android_id | ||
return android_id | ||
|
||
def get_version(): | ||
version = run_get_output(''' adb shell dumpsys package com.snapchat.android ''') | ||
p = re.compile('versionName=(.*)') | ||
print p.findall(version)[0].strip() | ||
return p.findall(version)[0].strip() | ||
|
||
def pull_bananas_cache_file(): | ||
version38 = '' | ||
if VERSION >= '5.0.38.1': | ||
version38 = '1' | ||
run_blocking_cmd(''' adb pull /data/data/com.snapchat.android/cache/bananas%s encrypted_bananas_file ''' %version38) | ||
|
||
def snapchat_bananas_password(): | ||
m = md5() | ||
m.update( get_android_id() ) | ||
m.update('seems legit...') | ||
return m.hexdigest() | ||
|
||
def decrypt_bananas_file(): | ||
with open("encrypted_bananas_file") as encrypted_bananas: | ||
with open("decrypted_bananas_file",'w') as decrypted_bananas: | ||
cipher = AES.new(snapchat_bananas_password(), AES.MODE_ECB) | ||
decrypt_file(encrypted_bananas,decrypted_bananas,cipher ) | ||
|
||
def pull_images(): | ||
run_blocking_cmd(''' adb pull /data/data/com.snapchat.android/cache/received_image_snaps/ encrypted_received_image_snaps/ ''') | ||
|
||
def extract_key_and_iv(json_bananas): | ||
if VERSION < '5.0.38.1': | ||
key= json_bananas['a'] | ||
iv= json_bananas['b'] | ||
else: | ||
key= json_bananas[0] | ||
iv= json_bananas[1] | ||
return (base64.b64decode(key).encode('hex'),base64.b64decode(iv).encode('hex')) | ||
|
||
def decrypt_images(): | ||
if not os.path.exists('decrypted_received_image_snaps'): os.makedirs('decrypted_received_image_snaps') | ||
with open("decrypted_bananas_file") as json_file: | ||
bananas = json.loads(json_file.read().decode('utf8')) | ||
if not bananas.get('snapKeysAndIvs',None): | ||
print "Images were already viewed, the key and IV were deleted from the /cache/bananas file. Try reopening Snapchat to check if images where downloaded." | ||
exit(0) | ||
json_bananas = json.loads(bananas['snapKeysAndIvs'],encoding='utf8') | ||
if len(json_bananas) < len( os.listdir("encrypted_received_image_snaps") ): | ||
print "There are less keys than snaps, some snaps won't be able to be decrypted" | ||
for file_name in os.listdir("encrypted_received_image_snaps"): | ||
could_decrypt = False | ||
for snap_pair in json_bananas: | ||
(key,iv) = extract_key_and_iv( json_bananas[snap_pair] ) | ||
|
||
s = run_get_output('openssl aes-128-cbc -K %s -iv %s -d -in encrypted_received_image_snaps/%s -out decrypted_received_image_snaps/%s' %(key,iv,file_name,file_name)) | ||
if s == '': | ||
could_decrypt = True | ||
break | ||
#no error then the image was decoded properly | ||
if not could_decrypt: | ||
print "The image %s could not be decrypted, none of the keys in the bananas file worked" %file_name | ||
#break when decrypt work | ||
|
||
def decrypt_file(in_file, out_file, cipher): | ||
bs = AES.block_size | ||
next_chunk = '' | ||
finished = False | ||
while not finished: | ||
chunk, next_chunk = next_chunk, cipher.decrypt(in_file.read(1024 * bs)) | ||
if len(next_chunk) == 0: | ||
padding_length = ord(chunk[-1]) | ||
chunk = chunk[:-padding_length] | ||
finished = True | ||
out_file.write(chunk) | ||
|
||
if __name__ == '__main__': | ||
global VERSION | ||
VERSION = get_version() | ||
#stop the application to save the 'bananas file' | ||
run_blocking_cmd('adb shell am force-stop com.snapchat.android') | ||
pull_images() | ||
pull_bananas_cache_file() | ||
decrypt_bananas_file() | ||
decrypt_images() | ||
#Cleaning up | ||
run_blocking_cmd('rm encrypted_bananas_file decrypted_bananas_file') | ||
run_blocking_cmd('rm -r encrypted_received_image_snaps') |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.