Реализация на javascript
(0 чел.) 
  • Страница:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

ТЕМА: Реализация на javascript

Re: Реализация на javascript 2 года, 1 мес. назад #3246

  • vprokof
  • Осваиваюсь на форуме
  • Постов: 28
  • Репутация: 0
Попробуем подпись XML
XMLDSig: формат подписи XML

Заходим
github.com/yaronn/xml-crypto
Читаем

В новом директории xml-crypto делаем
npm install xml-crypto
npm install node-forge

Копируем туда ключи
AUTH_....p12
RSA256_....p12

Подправляем с условием, чтоб ключи и сертификаты читаем через node-forge
Копируем example.js в example.bak.js
Для того, чтобы в последующем оценить размер xml-crypto bundle'а для варианта с браузером.

xml-crypto\node_modules\xml-crypto\example\example.js
var forge = require('node-forge');
var select = require('xml-crypto').xpath
  , dom = require('xmldom').DOMParser
  , SignedXml = require('xml-crypto').SignedXml
  , FileKeyInfo = require('xml-crypto').FileKeyInfo  
  , fs = require('fs')


function SignKeyInfo(prefix) {
      this.getKeyInfo = function(key, prefix) {
        prefix = prefix || ''
        prefix = prefix ? prefix + ':' : prefix
        return "<" + prefix + "X509Data><" + prefix + "X509Certificate>" +
                     removeHeaderFromPem(forge.pki.certificateToPem(cert)) +  
                    "</" + prefix + "X509Certificate></" + prefix + "X509Data>"
      }
      this.getKey = function(keyInfo) {
        //you can use the keyInfo parameter to extract the key in any way you want       
        return forge.pki.privateKeyToPem(privateKey)
      }
    }

function ValidateKeyInfo(prefix) {
      this.getKeyInfo = function(key, prefix) {
        prefix = prefix || ''
        prefix = prefix ? prefix + ':' : prefix
        return "<" + prefix + "X509Data><" + prefix + "X509Certificate>" +
                     removeHeaderFromPem(forge.pki.certificateToPem(cert)) +  
                    "</" + prefix + "X509Certificate></" + prefix + "X509Data>"
      }
      this.getKey = function(keyInfo) {
        //you can use the keyInfo parameter to extract the key in any way you want       
        return forge.pki.certificateToPem(cert)
      }
    }



function removeHeaderFromPem(pem) {
  var lines = pem.split('\n');
  var encoded = '';
  for(var i = 0;i < lines.length;i++){
    if (lines[i].trim().length > 0 &&
        lines[i].indexOf('-BEGIN CERTIFICATE-') < 0 && 
        lines[i].indexOf('-BEGIN RSA PRIVATE KEY-') < 0 && 
        lines[i].indexOf('-BEGIN RSA PUBLIC KEY-') < 0 &&
        lines[i].indexOf('-BEGIN PUBLIC KEY-') < 0 &&
        lines[i].indexOf('-END CERTIFICATE-') < 0 &&
        lines[i].indexOf('-END PUBLIC KEY-') < 0 &&
        lines[i].indexOf('-END RSA PRIVATE KEY-') < 0 &&
        lines[i].indexOf('-END RSA PUBLIC KEY-') < 0) {
      encoded += lines[i].trim();
    }
  }
  return encoded;
}


function signXml(xml, xpath, key, dest)
{
  var sig = new SignedXml()
  //sig.signingKey = fs.readFileSync(key)
  sig.signingKey = key
  sig.addReference(xpath)
  sig.keyInfoProvider = new SignKeyInfo('ds')    
  sig.computeSignature(xml,{
  prefix: 'ds'
  })
  fs.writeFileSync(dest, sig.getSignedXml())
}

function validateXml(xml, key)
{
  var doc = new dom().parseFromString(xml)    
  var signature = select(doc, "/*/*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']")[0]
  var sig = new SignedXml()
//  sig.keyInfoProvider = new FileKeyInfo(key)
  sig.keyInfoProvider = new ValidateKeyInfo('ds')
  sig.loadSignature(signature.toString())
  var res = sig.checkSignature(xml)
  if (!res) console.log(sig.validationErrors)
  return res;
}

//----------------------------------------------------------------
//Начало

var keyFile = fs.readFileSync("./RSA256_....p12", 'binary');

var p12Asn1 = forge.asn1.fromDer(keyFile);

// pkcs12 с паролем
var p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, '123456');

var bags = p12.getBags({bagType: forge.pki.oids.certBag});

// Сертификат
var certBag = bags[forge.pki.oids.certBag][0];
var cert = certBag.cert;
//console.log(forge.pki.certificateToPem(cert));
//-----BEGIN CERTIFICATE-----

// Приватный ключ
var keyBags = p12.getBags({bagType: forge.pki.oids.pkcs8ShroudedKeyBag});
var keyBag = keyBags[forge.pki.oids.pkcs8ShroudedKeyBag][0];
var privateKey = keyBag.key;
//console.log(forge.pki.privateKeyToPem(privateKey));
//-----BEGIN RSA PRIVATE KEY-----


// Публичный ключ
var publicKey = forge.pki.setRsaPublicKey(privateKey.n, privateKey.e);
//console.log(forge.pki.publicKeyToPem(publicKey));
//-----BEGIN PUBLIC KEY-----


//----------------------------------------------------------------------------------
// Проверка XMLDSIG 


var xml = "<library>" +
            "<book>" +
              "<name>Harry Potter</name>" +
            "</book>" +
          "</library>"

//sign an xml document
//signXml(xml, 
//  "//*[local-name(.)='book']", 
//  "client.pem", 
//  "result.xml")


// Подписываем приватным ключом
signXml(xml, 
  "//*[local-name(.)='book']", 
  forge.pki.privateKeyToPem(privateKey), 
  "result.xml")


console.log("xml signed succesfully")

var signedXml = fs.readFileSync("result.xml").toString()
console.log("validating signature...")

//validate an xml document
//if (validateXml(signedXml, "client_public.pem"))
//Проверяем сертификатом
if (validateXml(signedXml, forge.pki.certificateToPem(cert)))

  console.log("signature is valid")
else
  console.log("signature not valid")



Запускаем
node example.js

Должно вывестись
"signature is valid"

Подписанный XML получается такой
:pinch: ВНИМАНИЕ: СПОЙЛЕР!
Изменено: 2 года, 1 мес. назад от vprokof.

Re: Реализация на javascript 2 года, 1 мес. назад #3247

  • vprokof
  • Осваиваюсь на форуме
  • Постов: 28
  • Репутация: 0
Оценим размер xml-crypto bundle'а для варианта с браузером.

идём на browserify.org/#install
устанавливаем браузерификатор
npm install -g browserify

идём на github.com/mishoo/UglifyJS2
устанавливаем компрессор
npm install uglify-js -g

example.bak.js Там только xml-crypto

browserify example.bak.js -o xml-crypto-bundle.js
uglifyjs --compress --mangle -o xml-crypto-bundle-min.js -- xml-crypto-bundle.js

Размер файла
xml-crypto-bundle-min.js
около 435 к
Многовато.

размер forge.min.js почти в два раза меньше
около 272 к
Изменено: 2 года, 1 мес. назад от vprokof.

Re: Реализация на javascript 2 года, 1 мес. назад #3249

  • vprokof
  • Осваиваюсь на форуме
  • Постов: 28
  • Репутация: 0
GOSTKNCA_...p12
использует свой
Провайдер Kalkan 1.2.398.3.10.1.1.1.1

Задача по подписанию ключами ГОСТ видится решаемой.
xml-crypto позволяет подключить свой алгоритм хеширования.
Насколько я понимаю,
ГОСТ Р 34.11-94 и ГОСТ 34.311-95
Это одно и тоже.

gostcrypto.com/index.html
Алгоритм ГОСТ Р 34.11-94 эта библиотека поддерживает.

Остаётся задача.
Каким образом достать ключи ГОСТ в формате PEM ?
gamma.kz/forum/index.php/topic,464.0.html
stackoverflow.com/questions/37156747/pdf...ent-verify-exception

Как к уже имеющимся криптопровайдерам
Export and import CryptoPro PrivateKey Container
Export and import SignalCom PrivateKey Container
Export and import ViPNet PrivateKey Container

Добавить
Export and import Kalkan PrivateKey Container

Хотя, может уже и нет смысла.
Россия в 2019 году собирается переходить на новые инструменты криптографии.
Старые алгоритмы работать не будут.
РусКрипто’2017
www.ruscrypto.ru/accotiation/archive/rc2017/
www.ruscrypto.ru/resource/summary/rc2017/ruscrypto_2017.zip
Изменено: 2 года, 1 мес. назад от vprokof.

Re: Реализация на javascript 1 год, 9 мес. назад #3403

  • tjunussov
  • Новый участник
  • Постов: 6
  • Репутация: -2
Ребята из Алматы - Стартап Подпиши - https://подпиши.онлайн/ сделали на js ( ГОСТ и RSA )
бегло пробежавшись вижу что используют forge crypto и gostcrypto.com/

Ребята из НУЦ создайте пожалуйста NCA.js для файловых ЭЦП в КЗ мне кажется что больше половины использует именно файловый вариант ЭЦП, а не Hardware
Изменено: 1 год, 9 мес. назад от tjunussov.

Re: Реализация на javascript 1 год, 9 мес. назад #3404

  • ololo
  • Живу я здесь
  • Постов: 464
  • Репутация: 57
Насчет "Подпиши"
1. Никто не дает гарантию, что у них криптофункций безопасны.
2. У пользователя можно угнать хранилище ключей, так как файл считывается целиком.
gg wp

Re: Реализация на javascript 1 год, 9 мес. назад #3405

  • tjunussov
  • Новый участник
  • Постов: 6
  • Репутация: -2
вы в целом про стартап, я согласен, но если этот JS библиотека будет отдаваться с pki.gov.kz
и даже сам процесс считывания подписи с браузера только со страницы pki.gov.kz, аля sso.gov.kz сделать бы....

я вижу это так
1) есть сайт который использует функционал ЭЦП авторизация/подпись, пользователь нажимает НАЧАТЬ ПОДПИСЬ
2) его перекидывает на страницу подконтрольную НУЦу типа sso.gov.kz, там включен js скрипт который может считывать и подписывать, клиент подписывает файловым сертификатом ну или оттуда же ему предлагается что то типа NCALayer'а для хардвейрных ЭЦП
3) после успешной подписи его перекидывает на изначальную страницу

Такой же процесс используется в интернет оплатах - epay.kkb.kz
  • Страница:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
FaLang translation system by Faboba