📜 ⬆️ ⬇️

My Yandex.Fotki Uploader (Myf) - the beginning of open testing

Hello% USERNAME%. It has been 10 days since the article about the plugin was published , which uploads photos by drag & drop on textarea graphic files .

Description for those who are not aware of the previous post:
Imagine a situation - you need to post a dozen photos in LiveJournal or on the forum. If you use Yandex. Photos for posting photos online, this plugin will help you a lot. Drag to the text field where you write the message, photos and wait for the html / bbcode tags to appear and appear with links to the photos.


')

Difficulties


The biggest challenge for me was solving this problem:

Currently, the service to issue authorization tokens only supports non-standard RSA encryption, so customers are required to use a special encryption library. The source texts of the library version for the C / C ++ language are available at download.yandex.ru/api-fotki/c-yamrsa.tar.gz .


The extension for FireFox is written in Javascript. I didn’t want to add a separate encrypt program for each OS ( Windows / Unix / MacOS ) to the extension.
In the process of communicating with people in Habré - I was found by lomik , who transferred the main logic of Yandex RSA to Python language.

Here is the script. Posted by: lomik

#-*- coding:utf-8 -*-<br/>
<br/>
import sys, copy<br/>

<br/>
if __name__ == '__main__' :<br/>
if len(sys.argv) != 3 : print "usage: python %s <public-key> <text>" % sys.argv[0]; sys.exit()<br/>

NSTR,ESTR = sys.argv[1].split( "#" )<br/>
DATA_ARR = [ord(x) for x in sys.argv[2]]<br/>
N,E,STEP_SIZE = int (NSTR,16), int (ESTR,16), len(NSTR)/2-1<br/>

<br/>
prev_crypted = [0]*STEP_SIZE<br/>
<br/>
hex_out = "" <br/>
for i in range(0,(len(DATA_ARR)-1)/STEP_SIZE+1):<br/>
tmp = DATA_ARR[i*STEP_SIZE:(i+1)*STEP_SIZE]<br/>
tmp = [tmp[i] ^ prev_crypted[i] for i in range(0,len(tmp))]<br/>

tmp.reverse()<br/>
plain = 0<br/>
for x in range(0,len(tmp)): plain+= tmp[x]*pow(256, x, N)<br/>
hex_result = "%x" % pow(plain,E,N)<br/>
hex_result = "" .join([ '0' ]*( len(NSTR)- len(hex_result))) + hex_result<br/>

<br/>
for x in range(0,min(len(hex_result),len(prev_crypted)*2),2):<br/>
prev_crypted[x/2] = int (hex_result[x:x+2],16)<br/>
<br/>
hex_out += ( "0" if len(tmp) < 16 else "" ) + ( "%x" % len(tmp)) + "00" # current size<br/>

ks = len(NSTR)/2<br/>
hex_out += ( "0" if ks < 16 else "" ) + ( "%x" % ks) + "00" # key size<br/>

hex_out += hex_result<br/>
<br/>
print hex_out.decode( "hex" ).encode( "base64" ).replace( "\n" , "" )
<br/>
<br/>


I didn’t have much choice, but I decided to port the Python script to JS :-)

The second problem was the limitation of JavaScript in terms of working with large numbers (BigInt), which leads to a loss of computational accuracy and, as a result, erroneous results. I was helped by a ready-made library of functions BigInt.js .

As auxiliary functions used:


As a result, such useful function turned out:

function encrypt_yarsa(key, toenc)
{
/* Encode string like RSA
* Ported to JS by Artur Khasanov
* EMail: artur[at]hasanov.ru
* Website: hasanov.ru
* JS source: wiki.hasanov.ru/software/yandex-rsa
* Ported from Python script written by lomik.habrahabr.ru
*/
var DATA_ARR = [];
var NSTR = key.split( '#' )[0];
var ESTR = key.split( '#' )[1];
var N = bigInt2str(str2bigInt(NSTR, 16,0),10);
var E = bigInt2str(str2bigInt(ESTR, 16,0),10);
var STEP_SIZE = NSTR.length/2-1;
var prev_crypted = new Array(STEP_SIZE);
var hex_out = "" ;
var plain = new String();
for (i=0;i<toenc.length;i++)DATA_ARR[i] = ord(toenc.substr(i,1));
for (i=0;i<parseInt((DATA_ARR.length-1)/STEP_SIZE)+1;i++){
tmp = DATA_ARR.slice(i*STEP_SIZE, (i+1)*STEP_SIZE);
for (j=0;j<tmp.length;j++)tmp[j] = (tmp[j] ^ prev_crypted[j]);
tmp.reverse();
var plain = int2bigInt(0,0);
for (x=0;x<tmp.length;x++){
pow = powMod(int2bigInt(256,0), int2bigInt(x,0), N);
pow_mult = mult(pow, int2bigInt(tmp[x],0));
plain = add(plain, pow_mult);
}
plain_pow = powMod(plain, str2bigInt(E,10,0), str2bigInt(N,10,0));
plain_pow_str = bigInt2str(plain_pow, 16);
hex_result = new Array((NSTR.length - plain_pow_str.length) + 1).join( '0' ) + plain_pow_str;
min_x = Math.min(hex_result.length, prev_crypted.length*2);
for (x=0;x<min_x;x=x+2)prev_crypted[x/2] = parseInt( "0x" +hex_result.substr(x, 2));
if (tmp.length < 16) hex_out+= "00" ;
hex_out += tmp.length.toString(16).toUpperCase() + "00" ;
ks = NSTR.length/2;
if (ks<16) hex_out += "0" ;
hex_out += ks.toString(16).toUpperCase() + "00" ;
hex_out += hex_result;

}
return base64Encode(hexDecode(hex_out.toLowerCase())).replace(/[\n\r\t]/g, "" );
}


* This source code was highlighted with Source Code Highlighter .


Integrated it into an extension for Firefox and it turned out pretty.

results


Every day for 30-40 minutes I studied XUL, JS features for working with settings, etc. And now I can safely present to everyone:

Settings window:


Status bar:



Install / Download Plugin: Myf on addons.mozilla.org (the main and only source of the plugin distribution)

* Now this plugin is lying in the sandbox on addons.mozilla.org and for it to become public, I need comments and comments there for refinement. The status in the sandbox does not allow the plugin to be updated via automatic update. I will try to get the plugin out of the sandbox as quickly as possible.

Future plans


Source: https://habr.com/ru/post/83710/


All Articles