>>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>>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<
15 | 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+/="}})();
16 | (function(u){function p(b,n,a,c,e,j,k){b=b+(n&a|~n&c)+e+k;return(b<>>32-j)+n}function d(b,n,a,c,e,j,k){b=b+(n&c|a&~c)+e+k;return(b<>>32-j)+n}function l(b,n,a,c,e,j,k){b=b+(n^a^c)+e+k;return(b<>>32-j)+n}function s(b,n,a,c,e,j,k){b=b+(a^(n|~c))+e+k;return(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])},
17 | _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]),
18 | 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,
19 | 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,
20 | 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/
21 | 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);
22 | (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>>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,
28 | 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,
29 | 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})},
30 | 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,
31 | 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)}})}();
32 | (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,
33 | 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>>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;dd||4>=j?k:b[l[k>>>24]]^x[l[k>>>16&255]]^q[l[k>>>
34 | 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>>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=
35 | 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)})();
36 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [angularjs-crypto](http://ngmodules.org/modules/angularjs-crypto)
2 | ==================
3 | [](https://travis-ci.org/pussinboots/angularjs-crypto)
4 | [](https://coveralls.io/r/pussinboots/angularjs-crypto?branch=master)
5 | [](https://david-dm.org/pussinboots/angularjs-crypto)
6 | [](https://angularjs-crypto.herokuapp.com/)
7 | [](https://unitcover.herokuapp.com/#/builds/pussinboots/angularjs-crypto/builds)
8 | [](https://codio.com/pussinboots/angularjs-crypto)
9 |
10 | [](https://gitter.im/pussinboots/angularjs-crypto)
11 |
12 | [](http://unitcover.herokuapp.com/#/builds/pussinboots/angularjs-crypto/builds)
13 |
14 | AngularJS Module that integrate cryptography functionality offers from the [crypto-js](https://code.google.com/p/crypto-js/) project for all http requests and response.
15 |
16 | Inprogress update to the new angularjs version but before protractor migration.
17 |
18 | ## Demo Application
19 |
20 | There is demo application that use this library to demonstrate the client side encryption and storing that encrypted data on a server. Retrieve this data back and decrypt on the client side to display the data.
21 |
22 | [Demo](https://secure-notes.herokuapp.com)
23 |
24 | [Source Code](https://github.com/pussinboots/secure-notes)
25 |
26 |
27 | ## Versions
28 |
29 | Actual there are two versions one for angularjs 1.2 and one for angularjs 1.3.
30 | - angularjs 1.2 use the 1.2 branch it is tested with the latest 1.2.28 version
31 | - angularjs 1.3 use the master branch it is tested with 1.3.13 version
32 |
33 | ## Feature Requests
34 |
35 | - support public private key encryption/decryption maybe by integrate this javascript [library](https://github.com/travist/jsencrypt)
36 | - encrypt / decrypt binary data like images (setup a working example and maybe support it directly with angularjs-crypto) [example image encryption](http://alicebobandmallory.com/articles/2010/10/14/encrypt-images-in-javascript)
37 |
38 | ## Code
39 | [anuglarjs-crypto.js](https://github.com/pussinboots/angularjs-crypto/blob/master/public/js/lib/angularjs-crypto.js)
40 |
41 | Dependencies
42 | ------------
43 | - [AngularJS 1.1.4 + ](http://angularjs.org/) (tested with 1.1.4, 1.2.16, 1.2.28, 1.3.13)
44 | - [Crypto-js 3.1.2 AES modul](https://raw.githubusercontent.com/pussinboots/angularjs-crypto/master/public/js/cryptojs/rollups/aes.js)
45 | - [Crypto-js 3.1.2 ecb mode](https://raw.githubusercontent.com/pussinboots/angularjs-crypto/master/public/js/cryptojs/components/mode-ecb.js)
46 |
47 | ## Bower Versions
48 |
49 | - 0.0.3 : support all ciphers that are supported by CryptoJS
50 | - 0.0.4 : support decryption of encoded reponse body
51 | - 1.2.0 : use it for 1.14 + and 1.2.x version of angularjs
52 | - 1.3.0 : use for angularjs 1.3.x
53 |
54 | ## Development
55 |
56 | To simplify the checkout and the setup of a full development environment with all needed dependencies the [vagrant-git](https://github.com/pussinboots/vagrant-git) project is used.
57 |
58 | But before we can use the [vagrant-git](https://github.com/pussinboots/vagrant-git) project first install all [reequieremnts](https://github.com/pussinboots/vagrant-git#requirements). It is implemented as nodejs application. Than you can install the [vagrant-git](https://github.com/pussinboots/vagrant-git) project follow this [instruction](https://github.com/pussinboots/vagrant-git#install). Usage turorial can be found [here](https://github.com/pussinboots/vagrant-git#usage).
59 |
60 | To setup a development vagrant box for this project execute the command below.
61 | ```bash
62 | vgit --repo pussinboots/angularjs-crypto
63 | ```
64 | It will checkpout the vagrant runtime repo and this project itslef.
65 |
66 | On Windows without ssh client
67 | ```bash
68 | vgit --g https --repo pussinboots/angularjs-crypto
69 | ```
70 | That use https instead of ssh protocol. The ssh protocol is the default used protocol. So the first execution will take a while to download the vagrant [base box](https://vagrantcloud.com/pussinboots/boxes/ubuntu-truly) defined in the Vagrantfile. Than it install the defined dependencies see below. When the login screen appear login with vagrant/vagrant than you have a ready to use development environment for that project up and running. The project will be checkout to the vagrant shared folder so that the Host and Guest operating systems can access the git clone.
71 |
72 | The vagrant-git configuration is defined in the [.vagrant.yml](.vagrant.yml) file. The configuration will be explained on the next line the [general explanetion](https://github.com/pussinboots/vagrant-git#project-configuration).
73 | ```yml
74 | repo:
75 | - pussinboots/vagrant-devel
76 | folder: /vagrant/project/angularjs-crypto
77 | deps:
78 | - sublime3
79 | - nodejs
80 | ```
81 |
82 | repo: defined the following github repo like https://github.com/pussinboots/vagrant-devel as the vagrant runtime repo where the [Vagrant configuration](https://github.com/pussinboots/vagrant-devel/blob/master/Vagrantfile) is placed that will be used for that project.
83 |
84 | folder: is only information for the Developer that will pe display before vagrant startup so that he or sher knows where the angularjs-crypto project root folder can be found.
85 |
86 | deps: defined the dependencies to be installed during vagrant provision.
87 |
88 |
89 |
90 | ## Install (bower)
91 |
92 | * bower install angularjs-crypto
93 | * js file is under the [bower_components/]angularjs-crypto/public/js/lib/angularjs-crypto.js
94 | ```html
95 |
96 |
97 |
98 |
99 | ```
100 |
101 | ## Install (manual)
102 |
103 | * download [js file](https://github.com/pussinboots/angularjs-crypto/blob/master/public/js/lib/angularjs-crypto.js)
104 | * download [js plugin file](https://github.com/pussinboots/angularjs-crypto/blob/master/public/js/lib/plugins/CryptoJSCipher.js)
105 | * download [cryptojs aes](https://raw.githubusercontent.com/pussinboots/angularjs-crypto/master/public/js/cryptojs/rollups/aes.js)
106 | * download [crypto mode-ecb](https://raw.githubusercontent.com/pussinboots/angularjs-crypto/master/public/js/cryptojs/components/mode-ecb.js)
107 | * added javascript file to your app html file
108 | ```html
109 |
110 |
111 |
112 |
113 | ```
114 |
115 | ## Usage
116 |
117 | * add modul dependency ('angularjs-crypto') to angular
118 | ```js
119 | var demoApp = angular.module('demoApp', ['services', 'angularjs-crypto']);
120 | ```
121 |
122 | Example Service Definition
123 |
124 | * configure the http request for automatic decryption/encryption detection by setting property crypt:true
125 |
126 | ```js
127 | 'use strict';
128 |
129 | angular.module('services', ['ngResource'], function ($provide) {
130 | $provide.factory('Data', function ($resource) {
131 | return $resource('/assets/config', {}, {
132 | query: {method: 'GET', isArray: false, crypt: true},
133 | queryNoCrypt: {method: 'GET'},
134 | save: {method: 'POST', params: {}, crypt: true},
135 | saveNoCrypt: {method: 'POST', params: {}}
136 | });
137 | });
138 | });
139 | ```
140 |
141 | * configure base64Key aes key for decryption/encryption
142 |
143 | ```js
144 | demoApp.run(['cfCryptoHttpInterceptor', function(cfCryptoHttpInterceptor) {
145 | cfCryptoHttpInterceptor.base64Key = "16rdKQfqN3L4TY7YktgxBw==";
146 | }])
147 | ```
148 |
149 | That's done now all json fields that end with the pattern (default: '_enc') will be encoded in requests and decoded in responses.
150 |
151 | Issues
152 | -------------
153 | - Report at the github [issue tracker](https://github.com/pussinboots/angularjs-crypto/issues)
154 |
155 | Todos
156 | -------------
157 | * configurable error handling strict or elegant mode
158 | * support for http ajax calls missing only ng resource calls are supported (under investigation)
159 | * add support of encrypted cookies that are decrypted on server side
160 |
161 | Features
162 | -------------
163 | * implements ciphers offered by the [crypto-js](https://code.google.com/p/crypto-js/) project
164 | * AES
165 | * DES
166 | * Triple DES
167 | * Rabbit
168 | * RC4, RC4Drop
169 | * configuration the cipher algorithm to use (aes is configured as default) (done [see](https://github.com/pussinboots/angularjs-crypto/blob/master/README.md#set-own-plugin-implementation-for-encoding-and-decoding)))
170 | * configuration a function that return the aes secret key to use for encryption/decryption
171 | * encoding of complete query and body for requests
172 | * encoding of query parameter fields that end with the pattern
173 | * configuration of encode/decode function so that you can plugin in your own implementation
174 | * configuration of the aes secret key to use for encryption/decryption
175 | * configuration of the field name pattern which determinate which fields will be encrypted/decrypted
176 | * aes encryption/decryption of http json requests and responses
177 | * only with mode [ECB](http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_codebook_.28ECB.29)
178 | * only with padding [Pkcs7](http://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS7)
179 | * automatic detection of encryption/decryption for json fields based on the naming rule all fields end with pattern (default: :enc) as it comes
180 | * reponse then decrypt
181 | * request then encrypt
182 | * only requests / responses of Content-Type: 'application/json;charset=utf-8' will be processed other types will skip crypt processing include auto detection
183 |
184 | Configuration
185 | -------------
186 |
187 | #### Set the base64Key for aes encryption/decryption
188 |
189 | ```js
190 | var demoApp = angular.module('demoApp', ['angularjs-crypto']);
191 | demoApp.run(['cfCryptoHttpInterceptor', function(cfCryptoHttpInterceptor) {
192 | cfCryptoHttpInterceptor.base64Key = "16rdKQfqN3L4TY7YktgxBw==";
193 | }])
194 | ```
195 |
196 | #### Set the field name pattern
197 |
198 | ```js
199 | var demoApp = angular.module('demoApp', ['angularjs-crypto']);
200 | demoApp.run(['cfCryptoHttpInterceptor', function(cfCryptoHttpInterceptor) {
201 | cfCryptoHttpInterceptor.pattern = "_enc"; //that is the default value
202 | }])
203 | ```
204 |
205 | #### Set own plugin implementation for encoding and decoding
206 |
207 | This make it now possible to simple add other CryptoJs cipher implementations like DES or even other crypto libraries as well. If i find the time than i will add at least the supported cipher from CryptoJs. An example implementation that use Crypto AES can be found [here](https://github.com/pussinboots/angularjs-crypto/blob/master/public/js/lib/CryptoJSPlugin.js)
208 | ```js
209 | var demoApp = angular.module('demoApp', ['angularjs-crypto']);
210 | demoApp.run(['cfCryptoHttpInterceptor', function(cfCryptoHttpInterceptor) {
211 | cfCryptoHttpInterceptor.plugin = {
212 | encode: function(plainValue, base64Key) {
213 | return plainValue;
214 | },
215 | decode : function(encryptedValue, base64Key) {
216 | return encryptedValue;
217 | }
218 | };
219 | }])
220 | ```
221 |
222 | #### configure the cipher algorithm to use
223 |
224 | ```js
225 | demoApp.run(['cfCryptoHttpInterceptor', function(cfCryptoHttpInterceptor) {
226 | cfCryptoHttpInterceptor.plugin = new CryptoJSCipher(CryptoJS.mode.ECB, CryptoJS.pad.Pkcs7, CryptoJS.DES)
227 | })
228 | ```
229 |
230 | - availabe ciphers that are supported by [CryptoJS](https://code.google.com/p/crypto-js/#Ciphers)
231 | ```js
232 | demoApp.run(['cfCryptoHttpInterceptor', function(cfCryptoHttpInterceptor) {
233 | cfCryptoHttpInterceptor.plugin = new CryptoJSCipher(CryptoJS.mode.ECB, CryptoJS.pad.Pkcs7, CryptoJS.AES)
234 | cfCryptoHttpInterceptor.plugin = new CryptoJSCipher(CryptoJS.mode.ECB, CryptoJS.pad.Pkcs7, CryptoJS.DES)
235 | cfCryptoHttpInterceptor.plugin = new CryptoJSCipher(CryptoJS.mode.ECB, CryptoJS.pad.Pkcs7, CryptoJS.TripleDES)
236 | cfCryptoHttpInterceptor.plugin = new CryptoJSCipher(CryptoJS.mode.ECB, CryptoJS.pad.Pkcs7, CryptoJS.Rabbit)
237 | cfCryptoHttpInterceptor.plugin = new CryptoJSCipher(CryptoJS.mode.ECB, CryptoJS.pad.Pkcs7, CryptoJS.RC4)
238 | cfCryptoHttpInterceptor.plugin = new CryptoJSCipher(CryptoJS.mode.ECB, CryptoJS.pad.Pkcs7, CryptoJS.RC4Drop)
239 | })
240 | ```
241 | #### Configure the Content-Type header for encryption/decryption
242 | ```
243 | demoApp.run(['cfCryptoHttpInterceptor', function(cfCryptoHttpInterceptor) {
244 | cfCryptoHttpInterceptor.contentHeaderCheck = new ContentHeaderCheck(['application/json', 'application/json_enc']);
245 | }
246 | ```
247 | The default configured Content-Type is shown above. That means only for request's and responses
248 | that have one of the aboved Content-Type will be enrypted/decrypted. For example if you perform a request with the Content-Type : 'text/plain'. This request will be skipped for encryption even if shouldCrypt is set to true.
249 |
250 | There is also the possibilities to implement your own ContentHeaderCheck that for example always return
251 | true. Like that own below.
252 |
253 | ```
254 | function ContentTypeDoesntMatterCheck() {
255 | return {
256 | check: function(contentType) {
257 | return true;
258 | }
259 | }
260 | }
261 | ```
262 | To use the new implemented ContentHeaderCheck apply following configuration code.
263 | ```
264 | demoApp.run(['cfCryptoHttpInterceptor', function(cfCryptoHttpInterceptor) {
265 | cfCryptoHttpInterceptor.contentHeaderCheck = new ContentTypeDoesntMatterCheck();
266 | }
267 | ```
268 |
269 | #### Activate console logging
270 |
271 | ```js
272 | var demoApp = angular.module('demoApp', ['angularjs-crypto']);
273 | demoApp.run(['cfCryptoHttpInterceptor', function(cfCryptoHttpInterceptor) {
274 | cfCryptoHttpInterceptor.logging = true; //the default value is false. True will log the decrypted and the encrypted values to the console.
275 | }])
276 | ```
277 |
278 | #### Complete encoding of query parameter
279 |
280 | ```js
281 | $provide.factory('Data', function ($resource) {
282 | return $resource('/assets/config', {}, {
283 | queryFullCrypt: {method: 'GET', isArray: false, fullcryptquery:true}
284 | });
285 | });
286 | ```
287 |
288 | #### Complete encoding of body
289 |
290 | ```js
291 | $provide.factory('Data', function ($resource) {
292 | return $resource('/assets/config', {}, {
293 | saveFullCrypt: {method: 'POST', fullcryptbody:true}
294 | });
295 | });
296 | ```
297 |
298 | ##Example
299 |
300 | #### Key Example
301 |
302 | Change the base64Key locally by read it from the rootScope.
303 |
304 | ```js
305 | var demoApp = angular.module('demoApp', ['angularjs-crypto']);
306 | demoApp.run(function(cfCryptoHttpInterceptor, $rootScope) {
307 | cfCryptoHttpInterceptor.base64Key = $rootScope.base64Key;
308 | cfCryptoHttpInterceptor.pattern = "_enc"; //default value but for a better understanding it is also defined here
309 | })
310 | ```
311 |
312 | #### Key Example Function
313 |
314 | Define a function which will be used to get the key for encryption/decryption is called
315 | for every encryption/decryption process.
316 |
317 | ```js
318 | var demoApp = angular.module('demoApp', ['angularjs-crypto']);
319 | demoApp.run(function(cfCryptoHttpInterceptor, $rootScope) {
320 | cfCryptoHttpInterceptor.base64KeyFunc = function() {
321 | return $rootScope.base64Key;
322 | }
323 | })
324 | ```
325 |
326 | With this html snippet you can edit the key to use only locally.
327 |
328 | ```html
329 |
330 | ```
331 |
332 | Example App
333 | -------------
334 |
335 | Setup a simple example app that use mongodb as persistence layer for storing encrypted data.
336 |
337 | [Github](https://github.com/pussinboots/secure-notes)
338 |
339 | [Live](https://secure-notes.herokuapp.com)
340 |
341 | Demo
342 | -------------
343 |
344 | live
345 | ------
346 |
347 | The http calls are mocked with angular-mock.
348 |
349 | [Http Get Example](http://angularjs-crypto.herokuapp.com/#/get)
350 |
351 | [Http Post Example](http://angularjs-crypto.herokuapp.com/#/post)
352 |
353 | [Http Get query parameters encoding ](http://angularjs-crypto.herokuapp.com/#/query)
354 |
355 | [Complete query encoding](http://angularjs-crypto.herokuapp.com/#/fullquery)
356 |
357 | [Complete body encoding](http://angularjs-crypto.herokuapp.com/#/fullbody)
358 |
359 | [Change base64Key Example](http://angularjs-crypto.herokuapp.com/#/key)
360 |
361 | local
362 | ------
363 |
364 | Two ways to run the demo app local one with play or second with nodejs.
365 |
366 | Dependencies
367 | * play 2.2.3 (optional)
368 | * nodejs 0.10.28
369 | * [karma-test runner](http://karma-runner.github.io/0.12/intro/installation.html)
370 |
371 | Start it with play
372 |
373 | play run
374 |
375 | Then go to
376 | * [Get Example](http://localhost:9000/#/get)
377 | * [Post Example](http://localhost:9000/#/post)
378 | * [Http Get query parameters encoding ](http://localhost:9000/#/query)
379 | * [Change base64Key Example](http://localhost:9000/#/key)
380 | * [Complete query encoding](http://localhost:9000/#/fullquery)
381 | * [Complete body encoding](http://localhost:9000/#/fullbody)
382 |
383 | Start it with nodejs
384 |
385 | node server.js
386 |
387 |
388 | Then go to
389 | * [Get Example](http://localhost:9000/#/get)
390 | * [Post Example](http://localhost:9000/#/post)
391 | * [Http Get query parameters encoding ](http://localhost:9000/#/query)
392 | * [Change base64Key Example](http://localhost:9000/#/key)
393 | * [Complete query encoding](http://localhost:9000/#/fullquery)
394 | * [Complete body encoding](http://localhost:9000/#/fullbody)
395 |
396 | Or run the karma test local with
397 |
398 | npm test
399 |
400 | Description
401 | -------------
402 |
403 | This angularjs module is part of the [bankapp](https://github.com/pussinboots/bankapp).
404 | The idea is to store encrypted data in a backend and decode it on the client side so that the backend
405 | doesn't know what kind of data it stores only the angularjs client and the storage process know the
406 | plain data.
407 |
408 | If you have question or want to take of the development than write me a mail at pussinboots666@googlemail.com.
409 |
410 | It is a very young project but with the support of wide open source tools like karma and travis it
411 | will flow soon i hope.
412 |
413 | License
414 | --------------
415 |
416 | angularjs-crypto is released under the [MIT License](http://opensource.org/licenses/MIT).
417 |
--------------------------------------------------------------------------------