qrcode API extension
This commit is contained in:
parent
d9ebd8b955
commit
efc6bb4c91
111
API/QRCODE.sh
111
API/QRCODE.sh
|
@ -32,33 +32,120 @@ mkdir -p ~/.zen/tmp/${MOATS}/
|
|||
if [[ ${QRCODE} == "station" ]]; then
|
||||
## GENERATE PLAYER G1 TO ZEN ACCOUNTING
|
||||
ISTATION=$($MY_PATH/../tools/make_image_ipfs_index_carousel.sh | tail -n 1)
|
||||
echo $ISTATION > ~/.zen/ISTATION
|
||||
## SEND TO ISTATION PAGE
|
||||
sed "s~_TWLINK_~${myIPFSGW}${ISTATION}/~g" ~/.zen/Astroport.ONE/templates/index.302 > ~/.zen/tmp/${MOATS}/index.redirect
|
||||
echo "url='"${myIPFSGW}${ISTATION}"'" >> ~/.zen/tmp/${MOATS}/index.redirect
|
||||
(
|
||||
cat ~/.zen/tmp/${MOATS}/index.redirect | nc -l -p ${PORT} -q 1 > /dev/null 2>&1
|
||||
) &
|
||||
|
||||
exit 0
|
||||
fi
|
||||
|
||||
## CHECK IF QRCODE is ASTRONAUTENS or G1PUB format
|
||||
ASTROPATH=$(grep $QRCODE ~/.zen/game/players/*/.playerns | cut -d ':' -f 1 | rev | cut -d '/' -f 2- | rev 2>/dev/null)
|
||||
if [[ $ASTROPATH != "" ]]; then
|
||||
rm ~/.zen/game/players/.current
|
||||
ln -s $ASTROPATH ~/.zen/game/players/.current
|
||||
echo "LINKING $ASTROPATH to .current"
|
||||
#### SELECT PARRAIN "G1PalPé"
|
||||
|
||||
## SEND TO TW PAGE
|
||||
sed "s~_TWLINK_~${myIPFSGW}${QRCODE}/~g" ~/.zen/Astroport.ONE/templates/index.302 > ~/.zen/tmp/${MOATS}/index.redirect
|
||||
echo "url='"${myIPFSGW}${QRCODE}"'" >> ~/.zen/tmp/${MOATS}/index.redirect
|
||||
(
|
||||
cat ~/.zen/tmp/${MOATS}/index.redirect | nc -l -p ${PORT} -q 1 > /dev/null 2>&1
|
||||
) &
|
||||
fi
|
||||
|
||||
## FILTRAGE NON G1 TO IPFS READY QRCODE
|
||||
ASTRONAUTENS=$(~/.zen/Astroport.ONE/tools/g1_to_ipfs.py ${QRCODE})
|
||||
[[ ! ${ASTRONAUTENS} ]] \
|
||||
ASTROTOIPFS=$(~/.zen/Astroport.ONE/tools/g1_to_ipfs.py ${QRCODE})
|
||||
[[ ! ${ASTROTOIPFS} ]] \
|
||||
&& (echo "$HTTPCORS ERROR - ASTRONAUTENS !!" | nc -l -p ${PORT} -q 1 > /dev/null 2>&1 &) \
|
||||
&& exit 1
|
||||
|
||||
echo ">>> ${QRCODE} g1_to_ipfs $ASTRONAUTENS"
|
||||
echo ">>> ${QRCODE} g1_to_ipfs $ASTROTOIPFS"
|
||||
|
||||
## SEND MESSAGE TO CESIUM+ ACCOUNT (ME or .current)
|
||||
MYPLAYERKEY=$(grep ${QRCODE} ~/.zen/game/players/*/secret.dunikey | cut -d ':' -f 1)
|
||||
[[ ! $MYPLAYERKEY ]] && MYPLAYERKEY="$HOME/.zen/game/players/.current/secret.dunikey"
|
||||
|
||||
## COUCOU MSG
|
||||
## CCHANGE +
|
||||
$MY_PATH/../tools/jaklis/jaklis.py -n $myGCHANGE -k $MYPLAYERKEY send -d "${QRCODE}" -t "COUCOU" -m "ASTROPORT CONTACT"
|
||||
## CESIUM +
|
||||
$MY_PATH/../tools/jaklis/jaklis.py -n $myCESIUM -k $MYPLAYERKEY send -d "${QRCODE}" -t "COUCOU" -m "ASTROPORT CONTACT"
|
||||
CURPLAYER=$(cat ~/.zen/game/players/.current/.player)
|
||||
CURG1=$(cat ~/.zen/game/players/.current/.g1pub)
|
||||
CURCOINS=$(~/.zen/Astroport.ONE/tools/timeout.sh -t 20 ${MY_PATH}/../tools/jaklis/jaklis.py balance -p ${CURG1})
|
||||
echo "CURRENT PLAYER : $CURCOINS G1"
|
||||
|
||||
|
||||
if [[ ${CURG1} == ${QRCODE} ]]; then
|
||||
|
||||
echo "SAME PLAYER AS CURRENT"
|
||||
|
||||
else
|
||||
## GET VISITOR G1 WANNET AMOUNT : VISITORCOINS
|
||||
VISITORCOINS=$(~/.zen/Astroport.ONE/tools/timeout.sh -t 20 ${MY_PATH}/../tools/jaklis/jaklis.py balance -p ${QRCODE})
|
||||
if [[ $VISITORCOINS == "" || $VISITORCOINS == "null" ]]; then
|
||||
PALPE=${RANDOM:0:2}
|
||||
else
|
||||
PALPE=0
|
||||
fi
|
||||
|
||||
## DOES CURRENT IS RICHER THAN 100 G1
|
||||
if [ $CURCOINS -gt 99 ]; then
|
||||
|
||||
## LE COMPTE VISITOR EST VIDE
|
||||
echo "## PARRAIN $CURPLAYER SEND $PALPE TO ${QRCODE}"
|
||||
## G1 PAYEMENT
|
||||
$MY_PATH/../tools/jaklis/jaklis.py -k ~/.zen/game/players/.current/secret.dunikey pay -a ${PALPE} -p ${QRCODE} -c "ASTRO:ZEN_${PALPE}" -m
|
||||
## MESSAGE CESIUM +
|
||||
$MY_PATH/../tools/jaklis/jaklis.py -n $myCESIUM -k $MYPLAYERKEY send -d "${QRCODE}" -t "CADEAU" \
|
||||
-m "ASTRO:${CURPLAYER} VOUS ENVOI ${PALPE} JUNE.
|
||||
GAGNEZ 100 JUNE EN PLUS !
|
||||
CREEZ ET GEOLOCALISEZ VOTRE COMPTE SUR https://gchange.fr \
|
||||
ENSUITE REVENEZ SCANNER VOTRE QRCODE"
|
||||
|
||||
else
|
||||
## CURRENT PLAYER IS TOO POOR
|
||||
PALPE=0
|
||||
echo "VISITEUR POSSEDE ${CURCOINS} G1"
|
||||
|
||||
## GET G1 WALLET HISTORY
|
||||
$MY_PATH/../tools/jaklis/jaklis.py history -p ${QRCODE} -j > ~/.zen/tmp/${MOATS}/g1history.json
|
||||
|
||||
## SCAN CCHANGE +
|
||||
curl -s ${myDATA}/user/profile/${QRCODE} > ~/.zen/tmp/${MOATS}/gchange.json
|
||||
## CHECK IF RELATED TO CESIUM
|
||||
CPUB=$(cat ~/.zen/tmp/${MOATS}/gchange.json | jq -r '._source.pubkey' 2>/dev/null)
|
||||
## SCAN GPUB CESIUM +
|
||||
curl -s ${myCESIUM}/user/profile/${QRCODE} > ~/.zen/tmp/${MOATS}/gplus.json 2>/dev/null
|
||||
|
||||
##### MEMBER ??
|
||||
if [[ $CPUB && $CPUB != 'null' ]]; then
|
||||
|
||||
## SCAN CPUB CESIUM +
|
||||
curl -s ${myCESIUM}/user/profile/${CPUB} > ~/.zen/tmp/${MOATS}/cplus.json 2>/dev/null
|
||||
|
||||
## LINKED CESIUM WALLET
|
||||
$MY_PATH/../tools/jaklis/jaklis.py -n $myCESIUM -k $MYPLAYERKEY send -d "${QRCODE}" -t "FORGERON" \
|
||||
-m "ASTROPORT. G1. FORGERON ET RESEAU DE CONFIANCE Ŋ1. \
|
||||
INSCRIVEZ VOTRE COMPTE GCHANGE SUR : https://astroport.copylaradio.com"
|
||||
|
||||
|
||||
|
||||
else
|
||||
|
||||
## EXTRACT GPS ... CONTINUE THE GAME
|
||||
|
||||
fi
|
||||
# $MY_PATH/../tools/jaklis/jaklis.py -n $myGCHANGE -k $MYPLAYERKEY send -d "${QRCODE}" -t "COUCOU" -m "ASTRO ZEN CONTACT"
|
||||
|
||||
fi
|
||||
|
||||
echo "************************************************************"
|
||||
echo "$VISITORCOINS (+ ${PALPE}) JUNE"
|
||||
echo "************************************************************"
|
||||
|
||||
|
||||
fi
|
||||
###################################################################################################
|
||||
# THAT=$2 AND=$3 THIS=$4 APPNAME=$5 WHAT=$6 OBJ=$7 VAL=$8
|
||||
### amzqr "$myASTROPORT/?qrcode=$G1PUB&junesec=$PASsec&askpass=$HPass&tw=$ASTRONAUTENS" \
|
||||
|
@ -68,12 +155,6 @@ if [[ $AND == "junesec" ]]; then
|
|||
echo "♥BOX♥BOX♥BOX♥BOX♥BOX"
|
||||
echo "MAGIC WORLD ASTRONAUT & WISHES"
|
||||
|
||||
COINS=$(~/.zen/Astroport.ONE/tools/timeout.sh -t 20 ${MY_PATH}/../tools/jaklis/jaklis.py balance -p ${QRCODE})
|
||||
[[ $COINS == "" || $COINS == "null" ]] \
|
||||
&& $MY_PATH/../tools/jaklis/jaklis.py -k ~/.zen/game/players/.current/secret.dunikey pay -a 50 -p ${QRCODE} -c "ASTRO:PASSPORT_ACTIVATION" -m
|
||||
echo "************************************************************"
|
||||
echo "$COINS (+ 50 JUNE IF EMPTY) "
|
||||
echo "************************************************************"
|
||||
|
||||
if [[ $APPNAME == "askpass" ]]; then
|
||||
echo ">> ASTRONAUT QRCODE $APPNAME"
|
||||
|
|
|
@ -67,7 +67,7 @@ echo "#############################################"
|
|||
echo "######### PATIENCE ######"
|
||||
echo "#############################################"
|
||||
# removed : sqlite
|
||||
for i in qrencode pv ca-certificates basez jq bc file gawk yt-dlp ffmpeg dnsutils ntpdate v4l-utils espeak vlc mp3info musl-dev openssl* detox nmap httrack html2text ssmtp imagemagick; do
|
||||
for i in qrencode pv gnupg ca-certificates basez jq bc file gawk yt-dlp ffmpeg dnsutils ntpdate v4l-utils espeak vlc mp3info musl-dev openssl* detox nmap httrack html2text ssmtp imagemagick; do
|
||||
if [ $(dpkg-query -W -f='${Status}' $i 2>/dev/null | grep -c "ok installed") -eq 0 ]; then
|
||||
echo ">>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Installation $i <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
|
||||
sudo apt install -y $i
|
||||
|
|
|
@ -61,10 +61,10 @@ header {
|
|||
</div>
|
||||
<h2>
|
||||
<div id="typed-strings">
|
||||
<p>Hébergement <span>/ <strong><em><a href="https://opencollective.com/monnaie-libre/projects/coeurbox" target="funding">LA ♥BOX</a></u></em></strong> /^3223</p>
|
||||
<p>Téléportez vos <em>DATA</em> 👍</span> dans IPFS^3222</p>
|
||||
<p>Activez le Voeu <strong><em><u>👉<a href="https://astroport.cancer.copylaradio.com">G1CopierYoutube</a>👈</u></em></strong>^3112</p>
|
||||
<p>🔥.^999.^888.^777.^666.^555.^444.3^333.2^222.1^111 Partez 🚀^4321</p>
|
||||
<p>Activez <span>/ <strong><em><a href="https://opencollective.com/monnaie-libre/projects/coeurbox" target="funding">LA ♥BOX</a></u></em></strong> /^3223</p>
|
||||
<p>Copiez une chaine <em>YOUTUBE</em> 👍</span> dans IPFS^3222</p>
|
||||
<p>Ajoutez des Voeux <strong><em><u>👉<a href="https://qwantic.com">OpenSource Planet</a>👈</u></em></strong>^3112</p>
|
||||
<p>🔥.^999.^888.^777.^666.^555.^444.3^333.2^222.1^111 Go 🚀^4321</p>
|
||||
</div>
|
||||
<span id="typed"></span>
|
||||
</h2>
|
||||
|
|
|
@ -27,7 +27,7 @@ if [[ ! -d $img_dir ]]; then
|
|||
"https://g1sms.fr/g1barre/image.php?pubkey=${pub}&target=20000&title=${PLAYER}&node=g1.asycn.io&start_date=2020-01-01&display_pubkey=true&display_qrcode=true"
|
||||
echo "GOT ~/.zen/tmp/carousel/${pub}.png"
|
||||
ASTRONAUTENS=$(cat ~/.zen/game/players/${PLAYER}/.playerns)
|
||||
echo "<a target=\"$PLAYER\" href=\"$myIPFS/ipns/$ASTRONAUTENS\" title=\"$PLAYER ($COINS G1)\">_REPLACE_</a>" > ~/.zen/tmp/carousel/${pub}.insert
|
||||
echo "<a target=\"$PLAYER\" href=\"$myASTROPORT/?qrcode=$ASTRONAUTENS\" title=\"$PLAYER ($COINS G1)\">_REPLACE_</a>" > ~/.zen/tmp/carousel/${pub}.insert
|
||||
|
||||
done
|
||||
img_dir="$HOME/.zen/tmp/carousel"
|
||||
|
@ -35,6 +35,7 @@ fi
|
|||
|
||||
#Set Path to HTML page
|
||||
html_file="/tmp/index.html"
|
||||
core_file="/tmp/core.html"
|
||||
|
||||
#Create HTML page
|
||||
echo "<!DOCTYPE html>
|
||||
|
@ -42,7 +43,10 @@ echo "<!DOCTYPE html>
|
|||
<head>
|
||||
<title>Astroport ZEN Gallery : $myIP</title>
|
||||
<meta charset=\"UTF-8\">
|
||||
<link rel=\"stylesheet\" href=\"/ipfs/QmX9QyopkTw9TdeC6yZpFzutfjNFWP36nzfPQTULc4cYVJ/bootstrap.min.css\">
|
||||
</head>
|
||||
<body>" > $html_file
|
||||
|
||||
echo "<link rel=\"stylesheet\" href=\"/ipfs/QmX9QyopkTw9TdeC6yZpFzutfjNFWP36nzfPQTULc4cYVJ/bootstrap.min.css\">
|
||||
<style>
|
||||
.carousel-item {
|
||||
background-color: #0B0C10;
|
||||
|
@ -54,22 +58,20 @@ echo "<!DOCTYPE html>
|
|||
background-color: #FFFFFF;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class=\"container\">
|
||||
<h2> Astroport $myHOST ZEN Gallery $(date) </h2>
|
||||
<div id=\"myCarousel\" class=\"carousel slide\" data-ride=\"carousel\">
|
||||
<!-- Indicators -->
|
||||
<ul class=\"carousel-indicators\">
|
||||
<li data-target=\"#myCarousel\" data-slide-to=\"0\" class=\"active\"></li>" > $html_file
|
||||
<li data-target=\"#myCarousel\" data-slide-to=\"0\" class=\"active\"></li>" > $core_file
|
||||
|
||||
#Loop over images
|
||||
num=1
|
||||
for i in "$img_dir"/*; do
|
||||
if [[ $i =~ \.(JPG|jpg|PNG|png|JPEG|jpeg|GIF|gif)$ ]]; then
|
||||
if [ $num -ne 1 ]; then
|
||||
echo " <li data-target=\"#myCarousel\" data-slide-to=\"$num\"></li>" >> $html_file
|
||||
echo " <li data-target=\"#myCarousel\" data-slide-to=\"$num\"></li>" >> $core_file
|
||||
fi
|
||||
num=$((num+1))
|
||||
fi
|
||||
|
@ -78,7 +80,7 @@ done
|
|||
echo " </ul>
|
||||
|
||||
<!-- The slideshow -->
|
||||
<div class=\"carousel-inner\">" >> $html_file
|
||||
<div class=\"carousel-inner\">" >> $core_file
|
||||
|
||||
#Loop over images
|
||||
num=1
|
||||
|
@ -102,11 +104,11 @@ if [[ $i =~ \.(JPG|jpg|PNG|png|JPEG|jpeg|GIF|gif)$ ]]; then
|
|||
if [ $num -eq 1 ]; then
|
||||
echo " <div class=\"carousel-item active\">
|
||||
$ZLINK
|
||||
</div>" >> $html_file
|
||||
</div>" >> $core_file
|
||||
else
|
||||
echo " <div class=\"carousel-item\">
|
||||
$ZLINK
|
||||
</div>" >> $html_file
|
||||
</div>" >> $core_file
|
||||
fi
|
||||
num=$((num+1))
|
||||
fi
|
||||
|
@ -126,13 +128,15 @@ echo " </div>
|
|||
|
||||
<script src=\"/ipfs/QmX9QyopkTw9TdeC6yZpFzutfjNFWP36nzfPQTULc4cYVJ/jquery-3.2.1.slim.min.js\"></script>
|
||||
<script src=\"/ipfs/QmX9QyopkTw9TdeC6yZpFzutfjNFWP36nzfPQTULc4cYVJ/popper.min.js\"></script>
|
||||
<script src=\"/ipfs/QmX9QyopkTw9TdeC6yZpFzutfjNFWP36nzfPQTULc4cYVJ/bootstrap.min.js\"></script>
|
||||
<script src=\"/ipfs/QmX9QyopkTw9TdeC6yZpFzutfjNFWP36nzfPQTULc4cYVJ/bootstrap.min.js\"></script>" >> $core_file
|
||||
|
||||
</body>
|
||||
cat $core_file >> $html_file
|
||||
echo "</body>
|
||||
</html>" >> $html_file
|
||||
|
||||
coreipfs=$(ipfs add -q $core_file)
|
||||
htmlipfs=$(ipfs add -q $html_file)
|
||||
[[ $XDG_SESSION_TYPE == 'x11' ]] && xdg-open http://ipfs.localhost:8080/ipfs/$htmlipfs
|
||||
echo /ipfs/$htmlipfs
|
||||
echo /ipfs/$core_file
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -0,0 +1,295 @@
|
|||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
/* AES counter-mode (CTR) implementation in JavaScript (c) Chris Veness 2005-2019 */
|
||||
/* MIT Licence */
|
||||
/* www.movable-type.co.uk/scripts/aes.html */
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
/* global WorkerGlobalScope */
|
||||
|
||||
|
||||
import Aes from './aes.js';
|
||||
|
||||
|
||||
/**
|
||||
* AesCtr: Counter-mode (CTR) wrapper for AES.
|
||||
*
|
||||
* This encrypts a Unicode string to produces a base64 ciphertext using 128/192/256-bit AES,
|
||||
* and the converse to decrypt an encrypted ciphertext.
|
||||
*
|
||||
* See csrc.nist.gov/publications/detail/sp/800-38a/final
|
||||
*/
|
||||
class AesCtr extends Aes {
|
||||
|
||||
/**
|
||||
* Encrypt a text using AES encryption in Counter mode of operation.
|
||||
*
|
||||
* Unicode multi-byte character safe.
|
||||
*
|
||||
* @param {string} plaintext - Source text to be encrypted.
|
||||
* @param {string} password - The password to use to generate a key for encryption.
|
||||
* @param {number} nBits - Number of bits to be used in the key; 128 / 192 / 256.
|
||||
* @returns {string} Encrypted text, base-64 encoded.
|
||||
*
|
||||
* @example
|
||||
* const encr = AesCtr.encrypt('big secret', 'pāşšŵōřđ', 256); // 'lwGl66VVwVObKIr6of8HVqJr'
|
||||
*/
|
||||
static encrypt(plaintext, password, nBits) {
|
||||
if (![ 128, 192, 256 ].includes(nBits)) throw new Error('Key size is not 128 / 192 / 256');
|
||||
plaintext = AesCtr.utf8Encode(String(plaintext));
|
||||
password = AesCtr.utf8Encode(String(password));
|
||||
|
||||
// use AES itself to encrypt password to get cipher key (using plain password as source for key
|
||||
// expansion) to give us well encrypted key (in real use hashed password could be used for key)
|
||||
const nBytes = nBits/8; // no bytes in key (16/24/32)
|
||||
const pwBytes = new Array(nBytes);
|
||||
for (let i=0; i<nBytes; i++) { // use 1st 16/24/32 chars of password for key
|
||||
pwBytes[i] = i<password.length ? password.charCodeAt(i) : 0;
|
||||
}
|
||||
let key = Aes.cipher(pwBytes, Aes.keyExpansion(pwBytes)); // gives us 16-byte key
|
||||
key = key.concat(key.slice(0, nBytes-16)); // expand key to 16/24/32 bytes long
|
||||
|
||||
// initialise 1st 8 bytes of counter block with nonce (NIST SP 800-38A §B.2): [0-1] = millisec,
|
||||
// [2-3] = random, [4-7] = seconds, together giving full sub-millisec uniqueness up to Feb 2106
|
||||
const timestamp = (new Date()).getTime(); // milliseconds since 1-Jan-1970
|
||||
const nonceMs = timestamp%1000;
|
||||
const nonceSec = Math.floor(timestamp/1000);
|
||||
const nonceRnd = Math.floor(Math.random()*0xffff);
|
||||
// for debugging: const [ nonceMs, nonceSec, nonceRnd ] = [ 0, 0, 0 ];
|
||||
const counterBlock = [ // 16-byte array; blocksize is fixed at 16 for AES
|
||||
nonceMs & 0xff, nonceMs >>>8 & 0xff,
|
||||
nonceRnd & 0xff, nonceRnd>>>8 & 0xff,
|
||||
nonceSec & 0xff, nonceSec>>>8 & 0xff, nonceSec>>>16 & 0xff, nonceSec>>>24 & 0xff,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
];
|
||||
|
||||
// and convert nonce to a string to go on the front of the ciphertext
|
||||
const nonceStr = counterBlock.slice(0, 8).map(i => String.fromCharCode(i)).join('');
|
||||
|
||||
// convert (utf-8) plaintext to byte array
|
||||
const plaintextBytes = plaintext.split('').map(ch => ch.charCodeAt(0));
|
||||
|
||||
// ------------ perform encryption ------------
|
||||
const ciphertextBytes = AesCtr.nistEncryption(plaintextBytes, key, counterBlock);
|
||||
|
||||
// convert byte array to (utf-8) ciphertext string
|
||||
const ciphertextUtf8 = ciphertextBytes.map(i => String.fromCharCode(i)).join('');
|
||||
|
||||
// base-64 encode ciphertext
|
||||
const ciphertextB64 = AesCtr.base64Encode(nonceStr+ciphertextUtf8);
|
||||
|
||||
return ciphertextB64;
|
||||
}
|
||||
|
||||
/**
|
||||
* NIST SP 800-38A sets out recommendations for block cipher modes of operation in terms of byte
|
||||
* operations. This implements the §6.5 Counter Mode (CTR).
|
||||
*
|
||||
* Oⱼ = CIPHₖ(Tⱼ) for j = 1, 2 … n
|
||||
* Cⱼ = Pⱼ ⊕ Oⱼ for j = 1, 2 … n-1
|
||||
* C*ₙ = P* ⊕ MSBᵤ(Oₙ) final (partial?) block
|
||||
* where CIPHₖ is the forward cipher function, O output blocks, P plaintext blocks, C
|
||||
* ciphertext blocks
|
||||
*
|
||||
* @param {number[]} plaintext - Plaintext to be encrypted, as byte array.
|
||||
* @param {number[]} key - Key to be used to encrypt plaintext.
|
||||
* @param {number[]} counterBlock - Initial 16-byte CTR counter block (with nonce & 0 counter).
|
||||
* @returns {number[]} Ciphertext as byte array.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
static nistEncryption(plaintext, key, counterBlock) {
|
||||
const blockSize = 16; // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
|
||||
|
||||
// generate key schedule - an expansion of the key into distinct Key Rounds for each round
|
||||
const keySchedule = Aes.keyExpansion(key);
|
||||
|
||||
const blockCount = Math.ceil(plaintext.length/blockSize);
|
||||
const ciphertext = new Array(plaintext.length);
|
||||
|
||||
for (let b=0; b<blockCount; b++) {
|
||||
// ---- encrypt counter block; Oⱼ = CIPHₖ(Tⱼ) ----
|
||||
const cipherCntr = Aes.cipher(counterBlock, keySchedule);
|
||||
|
||||
// block size is reduced on final block
|
||||
const blockLength = b<blockCount-1 ? blockSize : (plaintext.length-1)%blockSize + 1;
|
||||
|
||||
// ---- xor plaintext with ciphered counter byte-by-byte; Cⱼ = Pⱼ ⊕ Oⱼ ----
|
||||
for (let i=0; i<blockLength; i++) {
|
||||
ciphertext[b*blockSize + i] = cipherCntr[i] ^ plaintext[b*blockSize + i];
|
||||
}
|
||||
|
||||
// increment counter block (counter in 2nd 8 bytes of counter block, big-endian)
|
||||
counterBlock[blockSize-1]++;
|
||||
// and propagate carry digits
|
||||
for (let i=blockSize-1; i>=8; i--) {
|
||||
counterBlock[i-1] += counterBlock[i] >> 8;
|
||||
counterBlock[i] &= 0xff;
|
||||
}
|
||||
|
||||
// if within web worker, announce progress every 1000 blocks (roughly every 50ms)
|
||||
if (typeof WorkerGlobalScope != 'undefined' && self instanceof WorkerGlobalScope) {
|
||||
if (b%1000 == 0) self.postMessage({ progress: b/blockCount });
|
||||
}
|
||||
}
|
||||
|
||||
return ciphertext;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decrypt a text encrypted by AES in counter mode of operation.
|
||||
*
|
||||
* @param {string} ciphertext - Cipher text to be decrypted.
|
||||
* @param {string} password - Password to use to generate a key for decryption.
|
||||
* @param {number} nBits - Number of bits to be used in the key; 128 / 192 / 256.
|
||||
* @returns {string} Decrypted text
|
||||
*
|
||||
* @example
|
||||
* const decr = AesCtr.decrypt('lwGl66VVwVObKIr6of8HVqJr', 'pāşšŵōřđ', 256); // 'big secret'
|
||||
*/
|
||||
static decrypt(ciphertext, password, nBits) {
|
||||
if (![ 128, 192, 256 ].includes(nBits)) throw new Error('Key size is not 128 / 192 / 256');
|
||||
ciphertext = AesCtr.base64Decode(String(ciphertext));
|
||||
password = AesCtr.utf8Encode(String(password));
|
||||
|
||||
// use AES to encrypt password (mirroring encrypt routine)
|
||||
const nBytes = nBits/8; // no bytes in key
|
||||
const pwBytes = new Array(nBytes);
|
||||
for (let i=0; i<nBytes; i++) { // use 1st nBytes chars of password for key
|
||||
pwBytes[i] = i<password.length ? password.charCodeAt(i) : 0;
|
||||
}
|
||||
let key = Aes.cipher(pwBytes, Aes.keyExpansion(pwBytes));
|
||||
key = key.concat(key.slice(0, nBytes-16)); // expand key to 16/24/32 bytes long
|
||||
|
||||
// recover nonce from 1st 8 bytes of ciphertext into 1st 8 bytes of counter block
|
||||
const counterBlock = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ];
|
||||
for (let i=0; i<8; i++) counterBlock[i] = ciphertext.charCodeAt(i);
|
||||
|
||||
// convert ciphertext to byte array (skipping past initial 8 bytes)
|
||||
const ciphertextBytes = new Array(ciphertext.length-8);
|
||||
for (let i=8; i<ciphertext.length; i++) ciphertextBytes[i-8] = ciphertext.charCodeAt(i);
|
||||
|
||||
// ------------ perform decryption ------------
|
||||
const plaintextBytes = AesCtr.nistDecryption(ciphertextBytes, key, counterBlock);
|
||||
|
||||
// convert byte array to (utf-8) plaintext string
|
||||
const plaintextUtf8 = plaintextBytes.map(i => String.fromCharCode(i)).join('');
|
||||
|
||||
// decode from UTF8 back to Unicode multi-byte chars
|
||||
const plaintext = AesCtr.utf8Decode(plaintextUtf8);
|
||||
|
||||
return plaintext;
|
||||
}
|
||||
|
||||
/**
|
||||
* NIST SP 800-38A sets out recommendations for block cipher modes of operation in terms of byte
|
||||
* operations. This implements the §6.5 Counter Mode (CTR).
|
||||
*
|
||||
* Oⱼ = CIPHₖ(Tⱼ) for j = 1, 2 … n
|
||||
* Pⱼ = Cⱼ ⊕ Oⱼ for j = 1, 2 … n-1
|
||||
* P*ₙ = C* ⊕ MSBᵤ(Oₙ) final (partial?) block
|
||||
* where CIPHₖ is the forward cipher function, O output blocks, C ciphertext blocks, P
|
||||
* plaintext blocks
|
||||
*
|
||||
* @param {number[]} ciphertext - Ciphertext to be decrypted, as byte array.
|
||||
* @param {number[]} key - Key to be used to decrypt ciphertext.
|
||||
* @param {number[]} counterBlock - Initial 16-byte CTR counter block (with nonce & 0 counter).
|
||||
* @returns {number[]} Plaintext as byte array.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
static nistDecryption(ciphertext, key, counterBlock) {
|
||||
const blockSize = 16; // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
|
||||
|
||||
// generate key schedule - an expansion of the key into distinct Key Rounds for each round
|
||||
const keySchedule = Aes.keyExpansion(key);
|
||||
|
||||
const blockCount = Math.ceil(ciphertext.length/blockSize);
|
||||
const plaintext = new Array(ciphertext.length);
|
||||
|
||||
for (let b=0; b<blockCount; b++) {
|
||||
// ---- decrypt counter block; Oⱼ = CIPHₖ(Tⱼ) ----
|
||||
const cipherCntr = Aes.cipher(counterBlock, keySchedule);
|
||||
|
||||
// block size is reduced on final block
|
||||
const blockLength = b<blockCount-1 ? blockSize : (ciphertext.length-1)%blockSize + 1;
|
||||
|
||||
// ---- xor ciphertext with ciphered counter byte-by-byte; Pⱼ = Cⱼ ⊕ Oⱼ ----
|
||||
for (let i=0; i<blockLength; i++) {
|
||||
plaintext[b*blockSize + i] = cipherCntr[i] ^ ciphertext[b*blockSize + i];
|
||||
}
|
||||
|
||||
// increment counter block (counter in 2nd 8 bytes of counter block, big-endian)
|
||||
counterBlock[blockSize-1]++;
|
||||
// and propagate carry digits
|
||||
for (let i=blockSize-1; i>=8; i--) {
|
||||
counterBlock[i-1] += counterBlock[i] >> 8;
|
||||
counterBlock[i] &= 0xff;
|
||||
}
|
||||
|
||||
// if within web worker, announce progress every 1000 blocks (roughly every 50ms)
|
||||
if (typeof WorkerGlobalScope != 'undefined' && self instanceof WorkerGlobalScope) {
|
||||
if (b%1000 == 0) self.postMessage({ progress: b/blockCount });
|
||||
}
|
||||
}
|
||||
|
||||
return plaintext;
|
||||
}
|
||||
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
|
||||
/**
|
||||
* Encodes multi-byte string to utf8.
|
||||
*
|
||||
* Note utf8Encode is an identity function with 7-bit ascii strings, but not with 8-bit strings;
|
||||
* utf8Encode('x') = 'x', but utf8Encode('ça') = 'ça', and utf8Encode('ça') = 'ça'.
|
||||
*/
|
||||
static utf8Encode(str) {
|
||||
try {
|
||||
return new TextEncoder().encode(str, 'utf-8').reduce((prev, curr) => prev + String.fromCharCode(curr), '');
|
||||
} catch (e) { // no TextEncoder available?
|
||||
return unescape(encodeURIComponent(str)); // monsur.hossa.in/2012/07/20/utf-8-in-javascript.html
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes utf8 string to multi-byte.
|
||||
*/
|
||||
static utf8Decode(str) {
|
||||
try {
|
||||
return new TextEncoder().decode(str, 'utf-8').reduce((prev, curr) => prev + String.fromCharCode(curr), '');
|
||||
} catch (e) { // no TextEncoder available?
|
||||
return decodeURIComponent(escape(str)); // monsur.hossa.in/2012/07/20/utf-8-in-javascript.html
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Encodes string as base-64.
|
||||
*
|
||||
* - developer.mozilla.org/en-US/docs/Web/API/window.btoa, nodejs.org/api/buffer.html
|
||||
* - note: btoa & Buffer/binary work on single-byte Unicode (C0/C1), so ok for utf8 strings, not for general Unicode...
|
||||
* - note: if btoa()/atob() are not available (eg IE9-), try github.com/davidchambers/Base64.js
|
||||
*/
|
||||
static base64Encode(str) {
|
||||
if (typeof btoa != 'undefined') return btoa(str); // browser
|
||||
if (typeof Buffer != 'undefined') return new Buffer(str, 'binary').toString('base64'); // Node.js
|
||||
throw new Error('No Base64 Encode');
|
||||
}
|
||||
|
||||
/*
|
||||
* Decodes base-64 encoded string.
|
||||
*/
|
||||
static base64Decode(str) {
|
||||
if (typeof atob != 'undefined') return atob(str); // browser
|
||||
if (typeof Buffer != 'undefined') return new Buffer(str, 'base64').toString('binary'); // Node.js
|
||||
throw new Error('No Base64 Decode');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
export default AesCtr;
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
CryptoJS v3.1.2
|
||||
code.google.com/p/crypto-js
|
||||
(c) 2009-2013 by Jeff Mott. All rights reserved.
|
||||
code.google.com/p/crypto-js/wiki/License
|
||||
*/
|
||||
var CryptoJS=CryptoJS||function(u,p){var d={},l=d.lib={},s=function(){},t=l.Base={extend:function(a){s.prototype=this;var c=new s;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}},
|
||||
r=l.WordArray=t.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=p?c:4*a.length},toString:function(a){return(a||v).stringify(this)},concat:function(a){var c=this.words,e=a.words,j=this.sigBytes;a=a.sigBytes;this.clamp();if(j%4)for(var k=0;k<a;k++)c[j+k>>>2]|=(e[k>>>2]>>>24-8*(k%4)&255)<<24-8*((j+k)%4);else if(65535<e.length)for(k=0;k<a;k+=4)c[j+k>>>2]=e[k>>>2];else c.push.apply(c,e);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<<
|
||||
32-8*(c%4);a.length=u.ceil(c/4)},clone:function(){var a=t.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],e=0;e<a;e+=4)c.push(4294967296*u.random()|0);return new r.init(c,a)}}),w=d.enc={},v=w.Hex={stringify:function(a){var c=a.words;a=a.sigBytes;for(var e=[],j=0;j<a;j++){var k=c[j>>>2]>>>24-8*(j%4)&255;e.push((k>>>4).toString(16));e.push((k&15).toString(16))}return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j<c;j+=2)e[j>>>3]|=parseInt(a.substr(j,
|
||||
2),16)<<24-4*(j%8);return new r.init(e,c/2)}},b=w.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var e=[],j=0;j<a;j++)e.push(String.fromCharCode(c[j>>>2]>>>24-8*(j%4)&255));return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j<c;j++)e[j>>>2]|=(a.charCodeAt(j)&255)<<24-8*(j%4);return new r.init(e,c)}},x=w.Utf8={stringify:function(a){try{return decodeURIComponent(escape(b.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return b.parse(unescape(encodeURIComponent(a)))}},
|
||||
q=l.BufferedBlockAlgorithm=t.extend({reset:function(){this._data=new r.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=x.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,e=c.words,j=c.sigBytes,k=this.blockSize,b=j/(4*k),b=a?u.ceil(b):u.max((b|0)-this._minBufferSize,0);a=b*k;j=u.min(4*a,j);if(a){for(var q=0;q<a;q+=k)this._doProcessBlock(e,q);q=e.splice(0,a);c.sigBytes-=j}return new r.init(q,j)},clone:function(){var a=t.clone.call(this);
|
||||
a._data=this._data.clone();return a},_minBufferSize:0});l.Hasher=q.extend({cfg:t.extend(),init:function(a){this.cfg=this.cfg.extend(a);this.reset()},reset:function(){q.reset.call(this);this._doReset()},update:function(a){this._append(a);this._process();return this},finalize:function(a){a&&this._append(a);return this._doFinalize()},blockSize:16,_createHelper:function(a){return function(b,e){return(new a.init(e)).finalize(b)}},_createHmacHelper:function(a){return function(b,e){return(new n.HMAC.init(a,
|
||||
e)).finalize(b)}}});var n=d.algo={};return d}(Math);
|
||||
(function(){var u=CryptoJS,p=u.lib.WordArray;u.enc.Base64={stringify:function(d){var l=d.words,p=d.sigBytes,t=this._map;d.clamp();d=[];for(var r=0;r<p;r+=3)for(var w=(l[r>>>2]>>>24-8*(r%4)&255)<<16|(l[r+1>>>2]>>>24-8*((r+1)%4)&255)<<8|l[r+2>>>2]>>>24-8*((r+2)%4)&255,v=0;4>v&&r+0.75*v<p;v++)d.push(t.charAt(w>>>6*(3-v)&63));if(l=t.charAt(64))for(;d.length%4;)d.push(l);return d.join("")},parse:function(d){var l=d.length,s=this._map,t=s.charAt(64);t&&(t=d.indexOf(t),-1!=t&&(l=t));for(var t=[],r=0,w=0;w<
|
||||
l;w++)if(w%4){var v=s.indexOf(d.charAt(w-1))<<2*(w%4),b=s.indexOf(d.charAt(w))>>>6-2*(w%4);t[r>>>2]|=(v|b)<<24-8*(r%4);r++}return p.create(t,r)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="}})();
|
||||
(function(u){function p(b,n,a,c,e,j,k){b=b+(n&a|~n&c)+e+k;return(b<<j|b>>>32-j)+n}function d(b,n,a,c,e,j,k){b=b+(n&c|a&~c)+e+k;return(b<<j|b>>>32-j)+n}function l(b,n,a,c,e,j,k){b=b+(n^a^c)+e+k;return(b<<j|b>>>32-j)+n}function s(b,n,a,c,e,j,k){b=b+(a^(n|~c))+e+k;return(b<<j|b>>>32-j)+n}for(var t=CryptoJS,r=t.lib,w=r.WordArray,v=r.Hasher,r=t.algo,b=[],x=0;64>x;x++)b[x]=4294967296*u.abs(u.sin(x+1))|0;r=r.MD5=v.extend({_doReset:function(){this._hash=new w.init([1732584193,4023233417,2562383102,271733878])},
|
||||
_doProcessBlock:function(q,n){for(var a=0;16>a;a++){var c=n+a,e=q[c];q[c]=(e<<8|e>>>24)&16711935|(e<<24|e>>>8)&4278255360}var a=this._hash.words,c=q[n+0],e=q[n+1],j=q[n+2],k=q[n+3],z=q[n+4],r=q[n+5],t=q[n+6],w=q[n+7],v=q[n+8],A=q[n+9],B=q[n+10],C=q[n+11],u=q[n+12],D=q[n+13],E=q[n+14],x=q[n+15],f=a[0],m=a[1],g=a[2],h=a[3],f=p(f,m,g,h,c,7,b[0]),h=p(h,f,m,g,e,12,b[1]),g=p(g,h,f,m,j,17,b[2]),m=p(m,g,h,f,k,22,b[3]),f=p(f,m,g,h,z,7,b[4]),h=p(h,f,m,g,r,12,b[5]),g=p(g,h,f,m,t,17,b[6]),m=p(m,g,h,f,w,22,b[7]),
|
||||
f=p(f,m,g,h,v,7,b[8]),h=p(h,f,m,g,A,12,b[9]),g=p(g,h,f,m,B,17,b[10]),m=p(m,g,h,f,C,22,b[11]),f=p(f,m,g,h,u,7,b[12]),h=p(h,f,m,g,D,12,b[13]),g=p(g,h,f,m,E,17,b[14]),m=p(m,g,h,f,x,22,b[15]),f=d(f,m,g,h,e,5,b[16]),h=d(h,f,m,g,t,9,b[17]),g=d(g,h,f,m,C,14,b[18]),m=d(m,g,h,f,c,20,b[19]),f=d(f,m,g,h,r,5,b[20]),h=d(h,f,m,g,B,9,b[21]),g=d(g,h,f,m,x,14,b[22]),m=d(m,g,h,f,z,20,b[23]),f=d(f,m,g,h,A,5,b[24]),h=d(h,f,m,g,E,9,b[25]),g=d(g,h,f,m,k,14,b[26]),m=d(m,g,h,f,v,20,b[27]),f=d(f,m,g,h,D,5,b[28]),h=d(h,f,
|
||||
m,g,j,9,b[29]),g=d(g,h,f,m,w,14,b[30]),m=d(m,g,h,f,u,20,b[31]),f=l(f,m,g,h,r,4,b[32]),h=l(h,f,m,g,v,11,b[33]),g=l(g,h,f,m,C,16,b[34]),m=l(m,g,h,f,E,23,b[35]),f=l(f,m,g,h,e,4,b[36]),h=l(h,f,m,g,z,11,b[37]),g=l(g,h,f,m,w,16,b[38]),m=l(m,g,h,f,B,23,b[39]),f=l(f,m,g,h,D,4,b[40]),h=l(h,f,m,g,c,11,b[41]),g=l(g,h,f,m,k,16,b[42]),m=l(m,g,h,f,t,23,b[43]),f=l(f,m,g,h,A,4,b[44]),h=l(h,f,m,g,u,11,b[45]),g=l(g,h,f,m,x,16,b[46]),m=l(m,g,h,f,j,23,b[47]),f=s(f,m,g,h,c,6,b[48]),h=s(h,f,m,g,w,10,b[49]),g=s(g,h,f,m,
|
||||
E,15,b[50]),m=s(m,g,h,f,r,21,b[51]),f=s(f,m,g,h,u,6,b[52]),h=s(h,f,m,g,k,10,b[53]),g=s(g,h,f,m,B,15,b[54]),m=s(m,g,h,f,e,21,b[55]),f=s(f,m,g,h,v,6,b[56]),h=s(h,f,m,g,x,10,b[57]),g=s(g,h,f,m,t,15,b[58]),m=s(m,g,h,f,D,21,b[59]),f=s(f,m,g,h,z,6,b[60]),h=s(h,f,m,g,C,10,b[61]),g=s(g,h,f,m,j,15,b[62]),m=s(m,g,h,f,A,21,b[63]);a[0]=a[0]+f|0;a[1]=a[1]+m|0;a[2]=a[2]+g|0;a[3]=a[3]+h|0},_doFinalize:function(){var b=this._data,n=b.words,a=8*this._nDataBytes,c=8*b.sigBytes;n[c>>>5]|=128<<24-c%32;var e=u.floor(a/
|
||||
4294967296);n[(c+64>>>9<<4)+15]=(e<<8|e>>>24)&16711935|(e<<24|e>>>8)&4278255360;n[(c+64>>>9<<4)+14]=(a<<8|a>>>24)&16711935|(a<<24|a>>>8)&4278255360;b.sigBytes=4*(n.length+1);this._process();b=this._hash;n=b.words;for(a=0;4>a;a++)c=n[a],n[a]=(c<<8|c>>>24)&16711935|(c<<24|c>>>8)&4278255360;return b},clone:function(){var b=v.clone.call(this);b._hash=this._hash.clone();return b}});t.MD5=v._createHelper(r);t.HmacMD5=v._createHmacHelper(r)})(Math);
|
||||
(function(){var u=CryptoJS,p=u.lib,d=p.Base,l=p.WordArray,p=u.algo,s=p.EvpKDF=d.extend({cfg:d.extend({keySize:4,hasher:p.MD5,iterations:1}),init:function(d){this.cfg=this.cfg.extend(d)},compute:function(d,r){for(var p=this.cfg,s=p.hasher.create(),b=l.create(),u=b.words,q=p.keySize,p=p.iterations;u.length<q;){n&&s.update(n);var n=s.update(d).finalize(r);s.reset();for(var a=1;a<p;a++)n=s.finalize(n),s.reset();b.concat(n)}b.sigBytes=4*q;return b}});u.EvpKDF=function(d,l,p){return s.create(p).compute(d,
|
||||
l)}})();
|
||||
CryptoJS.lib.Cipher||function(u){var p=CryptoJS,d=p.lib,l=d.Base,s=d.WordArray,t=d.BufferedBlockAlgorithm,r=p.enc.Base64,w=p.algo.EvpKDF,v=d.Cipher=t.extend({cfg:l.extend(),createEncryptor:function(e,a){return this.create(this._ENC_XFORM_MODE,e,a)},createDecryptor:function(e,a){return this.create(this._DEC_XFORM_MODE,e,a)},init:function(e,a,b){this.cfg=this.cfg.extend(b);this._xformMode=e;this._key=a;this.reset()},reset:function(){t.reset.call(this);this._doReset()},process:function(e){this._append(e);return this._process()},
|
||||
finalize:function(e){e&&this._append(e);return this._doFinalize()},keySize:4,ivSize:4,_ENC_XFORM_MODE:1,_DEC_XFORM_MODE:2,_createHelper:function(e){return{encrypt:function(b,k,d){return("string"==typeof k?c:a).encrypt(e,b,k,d)},decrypt:function(b,k,d){return("string"==typeof k?c:a).decrypt(e,b,k,d)}}}});d.StreamCipher=v.extend({_doFinalize:function(){return this._process(!0)},blockSize:1});var b=p.mode={},x=function(e,a,b){var c=this._iv;c?this._iv=u:c=this._prevBlock;for(var d=0;d<b;d++)e[a+d]^=
|
||||
c[d]},q=(d.BlockCipherMode=l.extend({createEncryptor:function(e,a){return this.Encryptor.create(e,a)},createDecryptor:function(e,a){return this.Decryptor.create(e,a)},init:function(e,a){this._cipher=e;this._iv=a}})).extend();q.Encryptor=q.extend({processBlock:function(e,a){var b=this._cipher,c=b.blockSize;x.call(this,e,a,c);b.encryptBlock(e,a);this._prevBlock=e.slice(a,a+c)}});q.Decryptor=q.extend({processBlock:function(e,a){var b=this._cipher,c=b.blockSize,d=e.slice(a,a+c);b.decryptBlock(e,a);x.call(this,
|
||||
e,a,c);this._prevBlock=d}});b=b.CBC=q;q=(p.pad={}).Pkcs7={pad:function(a,b){for(var c=4*b,c=c-a.sigBytes%c,d=c<<24|c<<16|c<<8|c,l=[],n=0;n<c;n+=4)l.push(d);c=s.create(l,c);a.concat(c)},unpad:function(a){a.sigBytes-=a.words[a.sigBytes-1>>>2]&255}};d.BlockCipher=v.extend({cfg:v.cfg.extend({mode:b,padding:q}),reset:function(){v.reset.call(this);var a=this.cfg,b=a.iv,a=a.mode;if(this._xformMode==this._ENC_XFORM_MODE)var c=a.createEncryptor;else c=a.createDecryptor,this._minBufferSize=1;this._mode=c.call(a,
|
||||
this,b&&b.words)},_doProcessBlock:function(a,b){this._mode.processBlock(a,b)},_doFinalize:function(){var a=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){a.pad(this._data,this.blockSize);var b=this._process(!0)}else b=this._process(!0),a.unpad(b);return b},blockSize:4});var n=d.CipherParams=l.extend({init:function(a){this.mixIn(a)},toString:function(a){return(a||this.formatter).stringify(this)}}),b=(p.format={}).OpenSSL={stringify:function(a){var b=a.ciphertext;a=a.salt;return(a?s.create([1398893684,
|
||||
1701076831]).concat(a).concat(b):b).toString(r)},parse:function(a){a=r.parse(a);var b=a.words;if(1398893684==b[0]&&1701076831==b[1]){var c=s.create(b.slice(2,4));b.splice(0,4);a.sigBytes-=16}return n.create({ciphertext:a,salt:c})}},a=d.SerializableCipher=l.extend({cfg:l.extend({format:b}),encrypt:function(a,b,c,d){d=this.cfg.extend(d);var l=a.createEncryptor(c,d);b=l.finalize(b);l=l.cfg;return n.create({ciphertext:b,key:c,iv:l.iv,algorithm:a,mode:l.mode,padding:l.padding,blockSize:a.blockSize,formatter:d.format})},
|
||||
decrypt:function(a,b,c,d){d=this.cfg.extend(d);b=this._parse(b,d.format);return a.createDecryptor(c,d).finalize(b.ciphertext)},_parse:function(a,b){return"string"==typeof a?b.parse(a,this):a}}),p=(p.kdf={}).OpenSSL={execute:function(a,b,c,d){d||(d=s.random(8));a=w.create({keySize:b+c}).compute(a,d);c=s.create(a.words.slice(b),4*c);a.sigBytes=4*b;return n.create({key:a,iv:c,salt:d})}},c=d.PasswordBasedCipher=a.extend({cfg:a.cfg.extend({kdf:p}),encrypt:function(b,c,d,l){l=this.cfg.extend(l);d=l.kdf.execute(d,
|
||||
b.keySize,b.ivSize);l.iv=d.iv;b=a.encrypt.call(this,b,c,d.key,l);b.mixIn(d);return b},decrypt:function(b,c,d,l){l=this.cfg.extend(l);c=this._parse(c,l.format);d=l.kdf.execute(d,b.keySize,b.ivSize,c.salt);l.iv=d.iv;return a.decrypt.call(this,b,c,d.key,l)}})}();
|
||||
(function(){for(var u=CryptoJS,p=u.lib.BlockCipher,d=u.algo,l=[],s=[],t=[],r=[],w=[],v=[],b=[],x=[],q=[],n=[],a=[],c=0;256>c;c++)a[c]=128>c?c<<1:c<<1^283;for(var e=0,j=0,c=0;256>c;c++){var k=j^j<<1^j<<2^j<<3^j<<4,k=k>>>8^k&255^99;l[e]=k;s[k]=e;var z=a[e],F=a[z],G=a[F],y=257*a[k]^16843008*k;t[e]=y<<24|y>>>8;r[e]=y<<16|y>>>16;w[e]=y<<8|y>>>24;v[e]=y;y=16843009*G^65537*F^257*z^16843008*e;b[k]=y<<24|y>>>8;x[k]=y<<16|y>>>16;q[k]=y<<8|y>>>24;n[k]=y;e?(e=z^a[a[a[G^z]]],j^=a[a[j]]):e=j=1}var H=[0,1,2,4,8,
|
||||
16,32,64,128,27,54],d=d.AES=p.extend({_doReset:function(){for(var a=this._key,c=a.words,d=a.sigBytes/4,a=4*((this._nRounds=d+6)+1),e=this._keySchedule=[],j=0;j<a;j++)if(j<d)e[j]=c[j];else{var k=e[j-1];j%d?6<d&&4==j%d&&(k=l[k>>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255]):(k=k<<8|k>>>24,k=l[k>>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255],k^=H[j/d|0]<<24);e[j]=e[j-d]^k}c=this._invKeySchedule=[];for(d=0;d<a;d++)j=a-d,k=d%4?e[j]:e[j-4],c[d]=4>d||4>=j?k:b[l[k>>>24]]^x[l[k>>>16&255]]^q[l[k>>>
|
||||
8&255]]^n[l[k&255]]},encryptBlock:function(a,b){this._doCryptBlock(a,b,this._keySchedule,t,r,w,v,l)},decryptBlock:function(a,c){var d=a[c+1];a[c+1]=a[c+3];a[c+3]=d;this._doCryptBlock(a,c,this._invKeySchedule,b,x,q,n,s);d=a[c+1];a[c+1]=a[c+3];a[c+3]=d},_doCryptBlock:function(a,b,c,d,e,j,l,f){for(var m=this._nRounds,g=a[b]^c[0],h=a[b+1]^c[1],k=a[b+2]^c[2],n=a[b+3]^c[3],p=4,r=1;r<m;r++)var q=d[g>>>24]^e[h>>>16&255]^j[k>>>8&255]^l[n&255]^c[p++],s=d[h>>>24]^e[k>>>16&255]^j[n>>>8&255]^l[g&255]^c[p++],t=
|
||||
d[k>>>24]^e[n>>>16&255]^j[g>>>8&255]^l[h&255]^c[p++],n=d[n>>>24]^e[g>>>16&255]^j[h>>>8&255]^l[k&255]^c[p++],g=q,h=s,k=t;q=(f[g>>>24]<<24|f[h>>>16&255]<<16|f[k>>>8&255]<<8|f[n&255])^c[p++];s=(f[h>>>24]<<24|f[k>>>16&255]<<16|f[n>>>8&255]<<8|f[g&255])^c[p++];t=(f[k>>>24]<<24|f[n>>>16&255]<<16|f[g>>>8&255]<<8|f[h&255])^c[p++];n=(f[n>>>24]<<24|f[g>>>16&255]<<16|f[h>>>8&255]<<8|f[k&255])^c[p++];a[b]=q;a[b+1]=s;a[b+2]=t;a[b+3]=n},keySize:8});u.AES=p._createHelper(d)})();
|
|
@ -1,28 +0,0 @@
|
|||
# Contribution
|
||||
|
||||
# Git Flow
|
||||
|
||||
The crypto-js project uses [git flow](https://github.com/nvie/gitflow) to manage branches.
|
||||
Do your changes on the `develop` or even better on a `feature/*` branch. Don't do any changes on the `master` branch.
|
||||
|
||||
# Pull request
|
||||
|
||||
Target your pull request on `develop` branch. Other pull request won't be accepted.
|
||||
|
||||
# How to build
|
||||
|
||||
1. Clone
|
||||
|
||||
2. Run
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
|
||||
3. Run
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
```
|
||||
|
||||
4. Check `build` folder
|
|
@ -1,24 +0,0 @@
|
|||
# License
|
||||
|
||||
[The MIT License (MIT)](http://opensource.org/licenses/MIT)
|
||||
|
||||
Copyright (c) 2009-2013 Jeff Mott
|
||||
Copyright (c) 2013-2016 Evan Vosberg
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -1,261 +0,0 @@
|
|||
# crypto-js [](https://travis-ci.org/brix/crypto-js)
|
||||
|
||||
JavaScript library of crypto standards.
|
||||
|
||||
## Node.js (Install)
|
||||
|
||||
Requirements:
|
||||
|
||||
- Node.js
|
||||
- npm (Node.js package manager)
|
||||
|
||||
```bash
|
||||
npm install crypto-js
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
ES6 import for typical API call signing use case:
|
||||
|
||||
```javascript
|
||||
import sha256 from 'crypto-js/sha256';
|
||||
import hmacSHA512 from 'crypto-js/hmac-sha512';
|
||||
import Base64 from 'crypto-js/enc-base64';
|
||||
|
||||
const message, nonce, path, privateKey; // ...
|
||||
const hashDigest = sha256(nonce + message);
|
||||
const hmacDigest = Base64.stringify(hmacSHA512(path + hashDigest, privateKey));
|
||||
```
|
||||
|
||||
Modular include:
|
||||
|
||||
```javascript
|
||||
var AES = require("crypto-js/aes");
|
||||
var SHA256 = require("crypto-js/sha256");
|
||||
...
|
||||
console.log(SHA256("Message"));
|
||||
```
|
||||
|
||||
Including all libraries, for access to extra methods:
|
||||
|
||||
```javascript
|
||||
var CryptoJS = require("crypto-js");
|
||||
console.log(CryptoJS.HmacSHA1("Message", "Key"));
|
||||
```
|
||||
|
||||
## Client (browser)
|
||||
|
||||
Requirements:
|
||||
|
||||
- Node.js
|
||||
- Bower (package manager for frontend)
|
||||
|
||||
```bash
|
||||
bower install crypto-js
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
Modular include:
|
||||
|
||||
```javascript
|
||||
require.config({
|
||||
packages: [
|
||||
{
|
||||
name: 'crypto-js',
|
||||
location: 'path-to/bower_components/crypto-js',
|
||||
main: 'index'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
require(["crypto-js/aes", "crypto-js/sha256"], function (AES, SHA256) {
|
||||
console.log(SHA256("Message"));
|
||||
});
|
||||
```
|
||||
|
||||
Including all libraries, for access to extra methods:
|
||||
|
||||
```javascript
|
||||
// Above-mentioned will work or use this simple form
|
||||
require.config({
|
||||
paths: {
|
||||
'crypto-js': 'path-to/bower_components/crypto-js/crypto-js'
|
||||
}
|
||||
});
|
||||
|
||||
require(["crypto-js"], function (CryptoJS) {
|
||||
console.log(CryptoJS.HmacSHA1("Message", "Key"));
|
||||
});
|
||||
```
|
||||
|
||||
### Usage without RequireJS
|
||||
|
||||
```html
|
||||
<script type="text/javascript" src="path-to/bower_components/crypto-js/crypto-js.js"></script>
|
||||
<script type="text/javascript">
|
||||
var encrypted = CryptoJS.AES(...);
|
||||
var encrypted = CryptoJS.SHA256(...);
|
||||
</script>
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
See: https://cryptojs.gitbook.io/docs/
|
||||
|
||||
### AES Encryption
|
||||
|
||||
#### Plain text encryption
|
||||
|
||||
```javascript
|
||||
var CryptoJS = require("crypto-js");
|
||||
|
||||
// Encrypt
|
||||
var ciphertext = CryptoJS.AES.encrypt('my message', 'secret key 123').toString();
|
||||
|
||||
// Decrypt
|
||||
var bytes = CryptoJS.AES.decrypt(ciphertext, 'secret key 123');
|
||||
var originalText = bytes.toString(CryptoJS.enc.Utf8);
|
||||
|
||||
console.log(originalText); // 'my message'
|
||||
```
|
||||
|
||||
#### Object encryption
|
||||
|
||||
```javascript
|
||||
var CryptoJS = require("crypto-js");
|
||||
|
||||
var data = [{id: 1}, {id: 2}]
|
||||
|
||||
// Encrypt
|
||||
var ciphertext = CryptoJS.AES.encrypt(JSON.stringify(data), 'secret key 123').toString();
|
||||
|
||||
// Decrypt
|
||||
var bytes = CryptoJS.AES.decrypt(ciphertext, 'secret key 123');
|
||||
var decryptedData = JSON.parse(bytes.toString(CryptoJS.enc.Utf8));
|
||||
|
||||
console.log(decryptedData); // [{id: 1}, {id: 2}]
|
||||
```
|
||||
|
||||
### List of modules
|
||||
|
||||
|
||||
- ```crypto-js/core```
|
||||
- ```crypto-js/x64-core```
|
||||
- ```crypto-js/lib-typedarrays```
|
||||
|
||||
---
|
||||
|
||||
- ```crypto-js/md5```
|
||||
- ```crypto-js/sha1```
|
||||
- ```crypto-js/sha256```
|
||||
- ```crypto-js/sha224```
|
||||
- ```crypto-js/sha512```
|
||||
- ```crypto-js/sha384```
|
||||
- ```crypto-js/sha3```
|
||||
- ```crypto-js/ripemd160```
|
||||
|
||||
---
|
||||
|
||||
- ```crypto-js/hmac-md5```
|
||||
- ```crypto-js/hmac-sha1```
|
||||
- ```crypto-js/hmac-sha256```
|
||||
- ```crypto-js/hmac-sha224```
|
||||
- ```crypto-js/hmac-sha512```
|
||||
- ```crypto-js/hmac-sha384```
|
||||
- ```crypto-js/hmac-sha3```
|
||||
- ```crypto-js/hmac-ripemd160```
|
||||
|
||||
---
|
||||
|
||||
- ```crypto-js/pbkdf2```
|
||||
|
||||
---
|
||||
|
||||
- ```crypto-js/aes```
|
||||
- ```crypto-js/tripledes```
|
||||
- ```crypto-js/rc4```
|
||||
- ```crypto-js/rabbit```
|
||||
- ```crypto-js/rabbit-legacy```
|
||||
- ```crypto-js/evpkdf```
|
||||
|
||||
---
|
||||
|
||||
- ```crypto-js/format-openssl```
|
||||
- ```crypto-js/format-hex```
|
||||
|
||||
---
|
||||
|
||||
- ```crypto-js/enc-latin1```
|
||||
- ```crypto-js/enc-utf8```
|
||||
- ```crypto-js/enc-hex```
|
||||
- ```crypto-js/enc-utf16```
|
||||
- ```crypto-js/enc-base64```
|
||||
|
||||
---
|
||||
|
||||
- ```crypto-js/mode-cfb```
|
||||
- ```crypto-js/mode-ctr```
|
||||
- ```crypto-js/mode-ctr-gladman```
|
||||
- ```crypto-js/mode-ofb```
|
||||
- ```crypto-js/mode-ecb```
|
||||
|
||||
---
|
||||
|
||||
- ```crypto-js/pad-pkcs7```
|
||||
- ```crypto-js/pad-ansix923```
|
||||
- ```crypto-js/pad-iso10126```
|
||||
- ```crypto-js/pad-iso97971```
|
||||
- ```crypto-js/pad-zeropadding```
|
||||
- ```crypto-js/pad-nopadding```
|
||||
|
||||
|
||||
## Release notes
|
||||
|
||||
### 4.1.1
|
||||
|
||||
Fix module order in bundled release.
|
||||
|
||||
Include the browser field in the released package.json.
|
||||
|
||||
### 4.1.0
|
||||
|
||||
Added url safe variant of base64 encoding. [357](https://github.com/brix/crypto-js/pull/357)
|
||||
|
||||
Avoid webpack to add crypto-browser package. [364](https://github.com/brix/crypto-js/pull/364)
|
||||
|
||||
### 4.0.0
|
||||
|
||||
This is an update including breaking changes for some environments.
|
||||
|
||||
In this version `Math.random()` has been replaced by the random methods of the native crypto module.
|
||||
|
||||
For this reason CryptoJS might not run in some JavaScript environments without native crypto module. Such as IE 10 or before or React Native.
|
||||
|
||||
### 3.3.0
|
||||
|
||||
Rollback, `3.3.0` is the same as `3.1.9-1`.
|
||||
|
||||
The move of using native secure crypto module will be shifted to a new `4.x.x` version. As it is a breaking change the impact is too big for a minor release.
|
||||
|
||||
### 3.2.1
|
||||
|
||||
The usage of the native crypto module has been fixed. The import and access of the native crypto module has been improved.
|
||||
|
||||
### 3.2.0
|
||||
|
||||
In this version `Math.random()` has been replaced by the random methods of the native crypto module.
|
||||
|
||||
For this reason CryptoJS might does not run in some JavaScript environments without native crypto module. Such as IE 10 or before.
|
||||
|
||||
If it's absolute required to run CryptoJS in such an environment, stay with `3.1.x` version. Encrypting and decrypting stays compatible. But keep in mind `3.1.x` versions still use `Math.random()` which is cryptographically not secure, as it's not random enough.
|
||||
|
||||
This version came along with `CRITICAL` `BUG`.
|
||||
|
||||
DO NOT USE THIS VERSION! Please, go for a newer version!
|
||||
|
||||
### 3.1.x
|
||||
|
||||
The `3.1.x` are based on the original CryptoJS, wrapped in CommonJS modules.
|
||||
|
||||
|
|
@ -1,234 +0,0 @@
|
|||
;(function (root, factory, undef) {
|
||||
if (typeof exports === "object") {
|
||||
// CommonJS
|
||||
module.exports = exports = factory(require("./core"), require("./enc-base64"), require("./md5"), require("./evpkdf"), require("./cipher-core"));
|
||||
}
|
||||
else if (typeof define === "function" && define.amd) {
|
||||
// AMD
|
||||
define(["./core", "./enc-base64", "./md5", "./evpkdf", "./cipher-core"], factory);
|
||||
}
|
||||
else {
|
||||
// Global (browser)
|
||||
factory(root.CryptoJS);
|
||||
}
|
||||
}(this, function (CryptoJS) {
|
||||
|
||||
(function () {
|
||||
// Shortcuts
|
||||
var C = CryptoJS;
|
||||
var C_lib = C.lib;
|
||||
var BlockCipher = C_lib.BlockCipher;
|
||||
var C_algo = C.algo;
|
||||
|
||||
// Lookup tables
|
||||
var SBOX = [];
|
||||
var INV_SBOX = [];
|
||||
var SUB_MIX_0 = [];
|
||||
var SUB_MIX_1 = [];
|
||||
var SUB_MIX_2 = [];
|
||||
var SUB_MIX_3 = [];
|
||||
var INV_SUB_MIX_0 = [];
|
||||
var INV_SUB_MIX_1 = [];
|
||||
var INV_SUB_MIX_2 = [];
|
||||
var INV_SUB_MIX_3 = [];
|
||||
|
||||
// Compute lookup tables
|
||||
(function () {
|
||||
// Compute double table
|
||||
var d = [];
|
||||
for (var i = 0; i < 256; i++) {
|
||||
if (i < 128) {
|
||||
d[i] = i << 1;
|
||||
} else {
|
||||
d[i] = (i << 1) ^ 0x11b;
|
||||
}
|
||||
}
|
||||
|
||||
// Walk GF(2^8)
|
||||
var x = 0;
|
||||
var xi = 0;
|
||||
for (var i = 0; i < 256; i++) {
|
||||
// Compute sbox
|
||||
var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4);
|
||||
sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63;
|
||||
SBOX[x] = sx;
|
||||
INV_SBOX[sx] = x;
|
||||
|
||||
// Compute multiplication
|
||||
var x2 = d[x];
|
||||
var x4 = d[x2];
|
||||
var x8 = d[x4];
|
||||
|
||||
// Compute sub bytes, mix columns tables
|
||||
var t = (d[sx] * 0x101) ^ (sx * 0x1010100);
|
||||
SUB_MIX_0[x] = (t << 24) | (t >>> 8);
|
||||
SUB_MIX_1[x] = (t << 16) | (t >>> 16);
|
||||
SUB_MIX_2[x] = (t << 8) | (t >>> 24);
|
||||
SUB_MIX_3[x] = t;
|
||||
|
||||
// Compute inv sub bytes, inv mix columns tables
|
||||
var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100);
|
||||
INV_SUB_MIX_0[sx] = (t << 24) | (t >>> 8);
|
||||
INV_SUB_MIX_1[sx] = (t << 16) | (t >>> 16);
|
||||
INV_SUB_MIX_2[sx] = (t << 8) | (t >>> 24);
|
||||
INV_SUB_MIX_3[sx] = t;
|
||||
|
||||
// Compute next counter
|
||||
if (!x) {
|
||||
x = xi = 1;
|
||||
} else {
|
||||
x = x2 ^ d[d[d[x8 ^ x2]]];
|
||||
xi ^= d[d[xi]];
|
||||
}
|
||||
}
|
||||
}());
|
||||
|
||||
// Precomputed Rcon lookup
|
||||
var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
|
||||
|
||||
/**
|
||||
* AES block cipher algorithm.
|
||||
*/
|
||||
var AES = C_algo.AES = BlockCipher.extend({
|
||||
_doReset: function () {
|
||||
var t;
|
||||
|
||||
// Skip reset of nRounds has been set before and key did not change
|
||||
if (this._nRounds && this._keyPriorReset === this._key) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Shortcuts
|
||||
var key = this._keyPriorReset = this._key;
|
||||
var keyWords = key.words;
|
||||
var keySize = key.sigBytes / 4;
|
||||
|
||||
// Compute number of rounds
|
||||
var nRounds = this._nRounds = keySize + 6;
|
||||
|
||||
// Compute number of key schedule rows
|
||||
var ksRows = (nRounds + 1) * 4;
|
||||
|
||||
// Compute key schedule
|
||||
var keySchedule = this._keySchedule = [];
|
||||
for (var ksRow = 0; ksRow < ksRows; ksRow++) {
|
||||
if (ksRow < keySize) {
|
||||
keySchedule[ksRow] = keyWords[ksRow];
|
||||
} else {
|
||||
t = keySchedule[ksRow - 1];
|
||||
|
||||
if (!(ksRow % keySize)) {
|
||||
// Rot word
|
||||
t = (t << 8) | (t >>> 24);
|
||||
|
||||
// Sub word
|
||||
t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff];
|
||||
|
||||
// Mix Rcon
|
||||
t ^= RCON[(ksRow / keySize) | 0] << 24;
|
||||
} else if (keySize > 6 && ksRow % keySize == 4) {
|
||||
// Sub word
|
||||
t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff];
|
||||
}
|
||||
|
||||
keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute inv key schedule
|
||||
var invKeySchedule = this._invKeySchedule = [];
|
||||
for (var invKsRow = 0; invKsRow < ksRows; invKsRow++) {
|
||||
var ksRow = ksRows - invKsRow;
|
||||
|
||||
if (invKsRow % 4) {
|
||||
var t = keySchedule[ksRow];
|
||||
} else {
|
||||
var t = keySchedule[ksRow - 4];
|
||||
}
|
||||
|
||||
if (invKsRow < 4 || ksRow <= 4) {
|
||||
invKeySchedule[invKsRow] = t;
|
||||
} else {
|
||||
invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t >>> 24]] ^ INV_SUB_MIX_1[SBOX[(t >>> 16) & 0xff]] ^
|
||||
INV_SUB_MIX_2[SBOX[(t >>> 8) & 0xff]] ^ INV_SUB_MIX_3[SBOX[t & 0xff]];
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
encryptBlock: function (M, offset) {
|
||||
this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX);
|
||||
},
|
||||
|
||||
decryptBlock: function (M, offset) {
|
||||
// Swap 2nd and 4th rows
|
||||
var t = M[offset + 1];
|
||||
M[offset + 1] = M[offset + 3];
|
||||
M[offset + 3] = t;
|
||||
|
||||
this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX);
|
||||
|
||||
// Inv swap 2nd and 4th rows
|
||||
var t = M[offset + 1];
|
||||
M[offset + 1] = M[offset + 3];
|
||||
M[offset + 3] = t;
|
||||
},
|
||||
|
||||
_doCryptBlock: function (M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) {
|
||||
// Shortcut
|
||||
var nRounds = this._nRounds;
|
||||
|
||||
// Get input, add round key
|
||||
var s0 = M[offset] ^ keySchedule[0];
|
||||
var s1 = M[offset + 1] ^ keySchedule[1];
|
||||
var s2 = M[offset + 2] ^ keySchedule[2];
|
||||
var s3 = M[offset + 3] ^ keySchedule[3];
|
||||
|
||||
// Key schedule row counter
|
||||
var ksRow = 4;
|
||||
|
||||
// Rounds
|
||||
for (var round = 1; round < nRounds; round++) {
|
||||
// Shift rows, sub bytes, mix columns, add round key
|
||||
var t0 = SUB_MIX_0[s0 >>> 24] ^ SUB_MIX_1[(s1 >>> 16) & 0xff] ^ SUB_MIX_2[(s2 >>> 8) & 0xff] ^ SUB_MIX_3[s3 & 0xff] ^ keySchedule[ksRow++];
|
||||
var t1 = SUB_MIX_0[s1 >>> 24] ^ SUB_MIX_1[(s2 >>> 16) & 0xff] ^ SUB_MIX_2[(s3 >>> 8) & 0xff] ^ SUB_MIX_3[s0 & 0xff] ^ keySchedule[ksRow++];
|
||||
var t2 = SUB_MIX_0[s2 >>> 24] ^ SUB_MIX_1[(s3 >>> 16) & 0xff] ^ SUB_MIX_2[(s0 >>> 8) & 0xff] ^ SUB_MIX_3[s1 & 0xff] ^ keySchedule[ksRow++];
|
||||
var t3 = SUB_MIX_0[s3 >>> 24] ^ SUB_MIX_1[(s0 >>> 16) & 0xff] ^ SUB_MIX_2[(s1 >>> 8) & 0xff] ^ SUB_MIX_3[s2 & 0xff] ^ keySchedule[ksRow++];
|
||||
|
||||
// Update state
|
||||
s0 = t0;
|
||||
s1 = t1;
|
||||
s2 = t2;
|
||||
s3 = t3;
|
||||
}
|
||||
|
||||
// Shift rows, sub bytes, add round key
|
||||
var t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++];
|
||||
var t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++];
|
||||
var t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++];
|
||||
var t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++];
|
||||
|
||||
// Set output
|
||||
M[offset] = t0;
|
||||
M[offset + 1] = t1;
|
||||
M[offset + 2] = t2;
|
||||
M[offset + 3] = t3;
|
||||
},
|
||||
|
||||
keySize: 256/32
|
||||
});
|
||||
|
||||
/**
|
||||
* Shortcut functions to the cipher's object interface.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var ciphertext = CryptoJS.AES.encrypt(message, key, cfg);
|
||||
* var plaintext = CryptoJS.AES.decrypt(ciphertext, key, cfg);
|
||||
*/
|
||||
C.AES = BlockCipher._createHelper(AES);
|
||||
}());
|
||||
|
||||
|
||||
return CryptoJS.AES;
|
||||
|
||||
}));
|
|
@ -1,39 +0,0 @@
|
|||
{
|
||||
"name": "crypto-js",
|
||||
"version": "4.1.1",
|
||||
"description": "JavaScript library of crypto standards.",
|
||||
"license": "MIT",
|
||||
"homepage": "http://github.com/brix/crypto-js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://github.com/brix/crypto-js.git"
|
||||
},
|
||||