• React Native + Nodejs 使用RSA加密登录


    想用rn做个RSA(非对称加密)登录

    基本流程就是在服务端生成RSA后,将“公钥”发到客户端,然后客户端用“公钥”加密信息发送到服务端,服务务端用私钥解密。

    过程不复杂,问题在于,nodejs和rn都准备用js做RSA加密,本来想用node-rsa做的,可是搞不懂它怎么设置公钥加密

    于是直接做node-rsa的基础库http://www-cs-students.stanford.edu/~tjw/jsbn/,简单封装了下做了个demo

    客户端:

    'use strict';
    const React = require('react-native');
    
    
    var url="192.168.1.103:8082"
    
    var RSAClient= require('./rsa-client');//客户端rsa加密
    var _publicKey = new RSAClient();
    
    //初始化“公钥”
    fetch('http://'+url+'/RSA')
      .then((response) => response.json())
      .then(
        (ret) => {
          _publicKey.setPublic(ret.n, ret.e);
        }
      ).done();
    
    //“公钥”加密,加密后的数据是hex编码比较长,所以转成base64
    var encrypt=function(val){
      var hex2b64 = require('./base64').hex2b64;
      return hex2b64(_publicKey.encrypt(val));
    };
    
    var login=function(data,doSuccess,doError){
        fetch('http://'+url+'/login',
            {
              method: 'POST',
              headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
              },
              body: JSON.stringify(data)
            })
        .then(function(response) {return response.json();})
        .then(
          function(resData){
            doSuccess(resData);
          }
        )
        .done();
    };
    
    var {      
        View,
        Text,
        TextInput,
        StyleSheet,
        TouchableOpacity
    } = React;
    
    
    var Index = React.createClass({  
      getInitialState: function() {
        return {
          userName: "",
          passWord: "",
          encrypted:""
        };
      },
      render:function() {
        return (
          <View style={{borderColor:'#FA6778',
                        justifyContent: 'center',
                        flex:1,
                        }}>
    
            <View style={{flex:1}}>
              <Text>encrypted = {this.state.encrypted}</Text>
    
              <Text>decrypted = {this.state.decrypted}</Text>
              
            </View>
        
    
            <View style={{flex:1.2}}>
              <View style={styles.singleLine}>
                <TextInput autoCapitalize="none"
                    style={{flex:1, fontSize: 16,padding: 6,borderWidth: 0,textDecorationLine :'none'}}
                    placeholder="User Name"
                    onChangeText={(text) =>
                  { this.setState({userName:text});}}
                  value={this.state.userName}
                  />
    
              </View>
              <View style={styles.singleLine}>
                <TextInput placeholder="PassWord"
                    password ={true}
                    style={{flex:1, fontSize: 16,padding: 6,borderWidth: 0,textDecorationLine :'none'}}
                    onChangeText={(text) =>
                  { this.setState({passWord:text});}}
                  value={this.state.passWord}
                  />
              </View>
    
            <TouchableOpacity style={styles.btn}
                              onPress={
                              ()=>
              {
              let _pwd= encrypt(this.state.passWord);
              login(
                {userName:this.state.userName,passWord:_pwd},
                (retJson) => {
                if(1==retJson.loginState){          
                  this.setState({encrypted:retJson.encrypted,decrypted:retJson.decrypted});
                }
              });
    
              }
              }>
              <Text style={{
                flex: 1,
                fontSize: 18,
                alignSelf: 'center',
              }}>OK</Text>
            </TouchableOpacity>
    
            </View>
    
            <View style={{flex:1}}></View>
    
    
         
        </View>);
      }
    });
    
    var styles = StyleSheet.create({
    btn: {
      alignSelf: 'stretch',
      alignItems: 'center',
      justifyContent: 'center',
      backgroundColor: '#3333FF',
      height: 40,
      borderRadius: 5,                          
      margin: 8,
      padding: 8,
    },
    singleLine: {
        height: 40,
        borderWidth: 1,
        borderRadius: 5, 
        borderColor: 'lightblue',
        margin: 15,
      },
    });
    module.exports=Index;

    服务端:

    var Router= require('router'),
        http = require('http'),
        fs = require('fs'),
        path = require('path');
    /*
    module.id
    module.filename
    module.loaded
    module.parent
    module.children
    console.log(module);
    */
    
    
    var router = Router()
    
    //**************RSA BEGIN************************
    var RSAService = require('./RSAService');
    var _key = new RSAService.rsaKey();
    _key.generate(384,"10001");
    /*
    console.log("Generating RSA Key...");
    console.log("_key e");
    console.log(_key.e.toString(16));
    console.log("_key n");
    console.log(_key.n.toString(16));
    console.log("_key d");
    console.log(_key.d.toString(16));
    console.log("_key p");
    console.log(_key.p.toString(16));
    console.log("_key q");
    console.log(_key.q.toString(16));
    console.log("_key dmp1");
    console.log(_key.dmp1.toString(16));
    console.log("_key dmq1");
    console.log(_key.dmq1.toString(16));
    console.log("_key coeff");
    console.log(_key.coeff.toString(16));
    */
    
    
    
    
    var hex2b64 = RSAService.hex2b64;
    var b64tohex= RSAService.b64tohex;
    
    var publicKey={e:_key.e.toString(16),n:_key.n.toString(16)};//公钥
    
    
    router.get('/RSA', 
    function (req, res) {
      res.setHeader('Content-Type', 'application/json; charset=utf-8')
    
        res.write(JSON.stringify(publicKey));
        res.end();
    });
    
    
    
    router.post('/login', function (req, res) {
        var _cnt=0;
        var body = '';
        req.on('data', 
          function (data) {
            body += data;
            _cnt++;
            // Too much POST data, kill the connection!
            // 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB
            if (body.length > 1e6)
                request.connection.destroy();
        });
    
        req.on('end', 
          function () {
            // var post = qs.parse(body);
            // use post['blah'], etc.
            var _state=1,_pwd='';
                var _pObj= JSON.parse(body);
                if(_pObj.passWord){
                    try{
                      _pwd =_key.decrypt(b64tohex(_pObj.passWord));// key.decrypt(_pObj.passWord, 'utf8');
                      console.log('_pwd: ', _pwd);
                    }catch(er){
                        console.log(er);
                _state=0;
                _pwd="ERROR";
                    }
    
                res.write(JSON.stringify({loginState:_state,encrypted:_pObj.passWord,decrypted:_pwd}));
                }
              res.end();
    
                console.log('time='+Date.now());
        });
    });
    
    
    
    
    var server = http.createServer(
        function(req, res) {
        console.log(req.url);
      router(req, res,
            function(req,res){});
    });
     
    server.listen(
        8082, '::',
        function () {
            console.log('http server listening on port 8082   time='+Date.now() );
        });

    客户端/服务端 RSA文件http://files.cnblogs.com/files/Grart/rsa.rar

  • 相关阅读:
    MySQL学习笔记
    Git常用命令
    MacBook Pro m1安装swoole PHP版本7.4
    斐波那契数列实现的2种方法
    归纳一些比较好用的函数
    阶乘的实现
    冒泡排序
    PHP上传图片
    PHPStorm常用快捷键
    DataTables的使用
  • 原文地址:https://www.cnblogs.com/Grart/p/5080228.html
Copyright © 2020-2023  润新知