Last time I've published about obfuscation was in 2019. Now with the new Javascript-engine and its new features like font control, the Legacy-engine is deprecated and the old method doesn't work anymore.
When it comes to obfuscate a whole project, I can recommend the CEP "MoCode" which is a great tool to develope Motion Graphics Templates. However I am missing the possibility to just obfuscate some part of my code. For example a function, leaving the rest of the code open, to be able to share my project with others who shell still be able to partially edit the project.
My current method is to use the node-js-Module javascript-obfuscator. There is an online website to run the module on https://www.obfuscator.io/. However for those who want to implement it into a pipeline, I recomment installing it locally. I have added my settings at the bottom of the article.
Surely there are other methods out there. Please let me know about it. If my described method has some flaws, please let me know, too. Thank you.
As an example let us use the Overshoot-expression from adobe.com:
Source code
// Sets up values to control overshoot.
// Link these to Slider expression controls to quickly preview different settings.
var amp = 40;
var freq = 30;
var decay = 50;
// Finds the most recent keyframe
var nK = nearestKey(time);
var n = (nK.time <= time) ? nK.index : --nK.index;
var t = (n === 0) ? 0 : time - key(n).time;
// If the current time is later than a keyframe, calculate overshoot.
// If not, use original value.
if ( n > 0 && t < 1 ) {
var v = velocityAtTime( key( n ).time - thisComp.frameDuration /10 );
value + v * amp * .001 * Math.sin(freq * .1 * t * 2 * Math.PI) / Math.exp(decay * .1 * t);
} else {
value;
}
Obfuscated code
var s=d;(function(e,f){var p=d,g=e();while(!![]){try{var h=parseInt(p(0x190))/0x1+-parseInt(p(0x18f))/0x2*(parseInt(p(0x1a1))/0x3)+parseInt(p(0x198))/0x4*(parseInt(p(0x1a2))/0x5)+-parseInt(p(0x19b))/0x6*(parseInt(p(0x196))/0x7)+parseInt(p(0x19c))/0x8*(parseInt(p(0x18c))/0x9)+-parseInt(p(0x19d))/0xa*(-parseInt(p(0x1a3))/0xb)+parseInt(p(0x1a0))/0xc*(-parseInt(p(0x19f))/0xd);if(h===f)break;else g['push'](g['shift']());}catch(i){g['push'](g['shift']());}}}(c,0x96f35));var b=(function(){var e=!![];return function(f,g){var h=e?function(){var q=d;if(g){var i=g[q(0x18b)](f,arguments);return g=null,i;}}:function(){};return e=![],h;};}()),a=b(this,function(){var r=d,f;try{var g=Function(r(0x193)+r(0x187)+');');f=g();}catch(o){f=window;}var h=f[r(0x197)]=f[r(0x197)]||{},i=[r(0x18e),r(0x191),r(0x19e),r(0x189),'exception',r(0x192),r(0x199)];for(var j=0x0;j<i['length'];j++){var k=b[r(0x194)]['prototype'][r(0x18a)](b),l=i[j],m=h[l]||k;k[r(0x186)]=b[r(0x18a)](b),k[r(0x195)]=m[r(0x195)]['bind'](m),h[l]=k;}});a();function d(a,b){var e=c();return d=function(f,g){f=f-0x186;var h=e[f];return h;},d(a,b);}function c(){var u=['constructor','toString','14JXwObj','console','681972jZgjNP','trace','exp','1136724RvGycP','40qWnzXa','3353820ylrPJV','info','2592772BerUns','24txdPer','3XreykH','5DkpuNl','22qWVEmm','__proto__','{}.constructor(\x22return\x20this\x22)(\x20)','time','error','bind','apply','2176803hmksLi','frameDuration','log','1658494pmNWSS','174744ARKuuz','warn','table','return\x20(function()\x20'];c=function(){return u;};return c();}var amp=0x28,freq=0x1e,decay=0x32,nK=nearestKey(time),n=nK['time']<=time?nK['index']:--nK['index'],t=n===0x0?0x0:time-key(n)[s(0x188)];if(n>0x0&&t<0x1){var v=velocityAtTime(key(n)[s(0x188)]-thisComp[s(0x18d)]/0xa);value+v*amp*0.001*Math['sin'](freq*0.1*t*0x2*Math['PI'])/Math[s(0x19a)](decay*0.1*t);}else value;
A little tipp I recommend to hold a library with your source code and obfuscated code together. In your After Effects project comment the obfuscated code with some information because it will be difficult to keep track of your code afterwards. I use a SHA-256 hash of my obfuscated parts which helps me to find the code in my library.
My settings for javascript-obfuscator are as follows:
target: 'node',
seed: 1,
disableConsoleOutput: true,
selfDefending: false,
debugProtection: false,
debugProtectionInterval: 0,
ignoreRequireImports: false,
sourceMap: false,
log: false,
stringArray: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayThreshold: 0.75,
stringArrayIndexShift: true,
stringArrayIndexesType: ['hexadecimal-number'],
stringArrayCallsTransform: false,
stringArrayCallsTransformThreshold: 0,
stringArrayWrappersCount: 1,
stringArrayWrappersType: 'variable',
stringArrayWrappersParametersMaxCount: 2,
stringArrayWrappersChainedCalls: true,
stringArrayEncoding: [],
splitStrings: false,
unicodeEscapeSequence: false,
forceTransformStrings: [],
reservedStrings: [],
identifierNamesGenerator: 'mangled',
identifiersPrefix: '',
renameGlobals: false,
renameProperties: false,
reservedNames: [],
compact: true,
simplify: true,
transformObjectKeys: false,
numbersToExpressions: false,
controlFlowFlattening: false,
controlFlowFlatteningThreshold: 0.75,
deadCodeInjection: false
Blog