一次有趣的Linux下.Net Core与C语言的合作开发体验:生成Linux标准的用户密码串

最近在项目进程中遇上了Linux用户验证的问题,想着怎么样通过Linux本地用户进行安全校验,于是去查了些资料。

Linux的密码存储

查阅资料后发现早期的Linux存储在/etc/password文件中,因为/etc/password权限控制较弱,现在已经不使用了,所以我们这里就不讨论这个文件了,较新的Linux发行版,密码都是存储在/etc/shadow文件中,因为/etc/shadow是管理员权限访问,安全性高出许多,我们可以使用命令来查看文件:

$ sudo cat /etc/shadow

以我真实的用户信息(用户名 inmount 密码 123456)为例:

......
inmount:$6$GTAgpXtw/YsqmaOJ$19/NZg8CVbQJB2BZBRFePGJj8f9Zme0s/VjmjdRjxJ9ItePem3h20tyGOk5Ytu5yIWio.0X.kwcsocfgIm2HY.:18211:0:99999:7:::
......

其中的$6$GTAgpXtw/YsqmaOJ$19/NZg8CVbQJB2BZBRFePGJj8f9Zme0s/VjmjdRjxJ9ItePem3h20tyGOk5Ytu5yIWio.0X.kwcsocfgIm2HY.就是用户密码加密后的字符串,$6代表为基于sha512加密运算,$GTAgpXtw/YsqmaOJ则是一串随机密钥。

使用 .Net Core 的进行简单尝试

针对字符串的简单观察后,采用.net core自带的 sha512再加base64尝试,结果计算结果与查询到的字符串天差地别,一度陷入尴尬的境地。

C语言中的密码函数

既然在.Net Core中没有现成的工具,于是就往C语言上靠一靠,于是乎,一个Linux下的密码函数浮出水面:

char * crypt (const char *key,const char * salt);

使用此函数,直接可以生成我们所需的密码。

探索Linux的动态链接库

作为一个长期奋斗在.Net环境中的程序员,想要调用Linux C函数库中的函数,如果放在几年前,那是想想都感觉自己是不是疯了的感觉,不过这.Net Core还是给了我们希望,在翻阅了了Githud上corefx库(也就是.Net Core的框架源代码)后,发现可以通过DllImport来调用Linux的so动态链接库。

于是,一个想法浮现在脑海中,使用C语言编译so动态库->使用.Net Core调用动态库来实现我们想要的功能。

制作so动态链接库

这一块,网上教程很多的,我就不多说了,贴上代码:

library.h

#ifndef CRYPT_LIBRARY_H
#define CRYPT_LIBRARY_H

char *getpassword(const char *key, const char *slat);

#endif //CRYPT_LIBRARY_H

library.c

#include "library.h"
#include <crypt.h>

char *getpassword(const char *key, const char *slat) {
    return crypt(key, slat);
}

编译so库:

gcc library.c -fPIC -shared -o libcrypt.so -lcrypt

得到了一个Linux下的标准动态连接库libcrypt.so文件。

使用.Net Core调用so文件

这个就更不用说了,直接上代码:

using System;
using System.Runtime.InteropServices;

namespace App {

    class Program {

        [DllImport("libcrypt.so",
            EntryPoint = "getpassword",
            CallingConvention = CallingConvention.Cdecl,
            CharSet = CharSet.Ansi,
            SetLastError = true)]
        public static extern IntPtr getpassword(IntPtr key, IntPtr slat);

        [DllImport("libcrypt.so",
            EntryPoint = "getpassword",
            CallingConvention = CallingConvention.Cdecl,
            CharSet = CharSet.Ansi,
            SetLastError = true)]
        public static extern string getpassword(string key, string slat);

        static void Main(string[] args) {
            Console.WriteLine(getpassword("123456", "$6$GTAgpXtw/YsqmaOJ"));
            Console.WriteLine(Marshal.PtrToStringAnsi(getpassword(Marshal.StringToHGlobalAnsi("123456"), Marshal.StringToHGlobalAnsi("$6$GTAgpXtw/YsqmaOJ"))));
        }
    }
}

代码中根据原函数定义中的字符指针的特点,可以使用字符串或者指针类型两种处理方式,其结果是一样的,下面是运行结果(需要将libcrypt.so文件拷贝到执行目录下,并在Linux环境下运行,在Windows环境下运行会提示错误):

$6$GTAgpXtw/YsqmaOJ$19/NZg8CVbQJB2BZBRFePGJj8f9Zme0s/VjmjdRjxJ9ItePem3h20tyGOk5Ytu5yIWio.0X.kwcsocfgIm2HY.
$6$GTAgpXtw/YsqmaOJ$19/NZg8CVbQJB2BZBRFePGJj8f9Zme0s/VjmjdRjxJ9ItePem3h20tyGOk5Ytu5yIWio.0X.kwcsocfgIm2HY.

吹一波.Net Core

通过这次的体验,发现结合C语言.Net Core可以在Linux下做几乎所有事情,之前在了解到.Net Core 3.0只支持Windows窗口化编程的遗憾一扫而空,将GTK(好像Mono有个叫GTK#的东西,估计差不多原理)或者WxWeight一类的,用so形式重新封装一下,感觉开发窗口化程序也不会是什么困难的事情(当然Linux下对窗口化的需求本来就比较低),反正不管怎么样,对.Net Core的未来是越来越有信心了。

原文地址:https://blog.51cto.com/5103803/2449492

时间: 2024-10-08 10:12:42

一次有趣的Linux下.Net Core与C语言的合作开发体验:生成Linux标准的用户密码串的相关文章

什么是core dump linux下用core和gdb查询出现&quot;段错误&quot;的地方

什么是core dump   linux下用core和gdb查询出现"段错误"的地方 http://blog.chinaunix.net/uid-26833883-id-3193279.html 有些时候我们在一段C代码的时候,由于对一个非法内存进行了操作,在程序运行的过程中,出现了"段错误". 呵呵,这种问题我想很多人会经常遇到.遇到这种问题是非常无语的,只是提示了"段错误",接着什么都没 有,如果我们一味的去看代码找太疼苦了,因为我们都相信自

linux下java程序与C语言程序通过SOCKET通信的简单例子

linux下java程序与C语言程序通过SOCKET通信的简单例子 今天上午实验了java程序与c语言程序通过socket进行通信.由于没学过java,因此只是编写了C语言端的代码,java端的代码是从网上别的文章中找的,经过少量修改后与C语言端程序通信成功. 本例中C语言端作为服务器,java端作为客户端 代码如下: /****************** server program *****************/ #include <stdio.h> #include <sy

Linux下零基础学C语言、C++系列实战视频教程

Linux下零基础跟我学C语言.C++系列实战教程(入门篇.项目实战与提高篇.软件设计与工程实践篇)适合人群:初级课时数量:194课时用到技术:C++涉及项目:windows版服务器端开发咨询qq:1840215592Linux下零基础学C语言.C++系列实战视频教程详细介绍:http://www.dwz.cn/Fk3mk1.1跟我一起学C(linux)课程详细介绍01.从helloworld程序认识计算机(一)Helloword程序什么是程序程序语言C程序执行环境02.从helloworld程

linux下代码生成core文件

我们都知道在linux环境下,通过ulimit -c size 命令能方便的打开或关闭coredump功能,从而生成core文件,便于调试.但是对于如何用代码控制生成core文件,可能很多人就不知道了.我们一起来看下,其实也很简单. 首先需要了解两个函数: int getrlimit(int resource, struct rlimit *rlim); int setrlimit(int resource, const struct rlimit *rlim); 这两个函数可以对系统的一些资源

linux下的ssh工具之,本地上传到linux服务器and Linux服务器文件另存为本地。非sftp工具。

首先,当你只有一个ssh工具可以连接linux,但你有想把文件在 linux 和windows(本地)直接的切换.其实可以的: 本文参考 1.将本地的文件,放到ssh远程的linux服务器上: 首先要安装工具包:   yum -y install lrzsz ok   操作方式是,在当前目录下 执行: rz    就会出现一个windows的弹框,选择你要上传到linux服务器上的文件点击确认就可以. 常用参数 -b 以二进制方式,默认为文本方式.(Binary (tell it like it

LINUX下使用elasticsearch-jdbc工具实现MySQL同步到ElasticSearch 以及linux 64位centos系统安装jdk1.8

第一步:环境匹配 1)elasticsearch 2.3.3 成功安装部署 2)mysql安装成功,增删改查无误~~. 3)要保证elasticsearch-jdbc的版本要与elasticsearch的版本是一致的(下面的内容会提示下载).否则会报错,无法进行之后的步骤. (例如elasticsearch-jdbc-2.3.3.0-dist.zip(对应的你的elaseticsearh-2.3.3) 4)(linux 64位centos下安装jdk1.8)(我的是CentOS release

在Linux下如何使用软盘、光盘以及DOS等非Linux分区

这是Linux初学者问得最多的问题.由于大家已习惯了微软的访问方法,总想用类似的思路来找 到软盘和光盘. 但在Linux下,却沿袭了UNIX将设备当作文件来处理的方法.所以要访问软盘和光盘,就必须先将 它们装载 到Linux系统的/mnt目录中来. 装载的命令是mount,格式如下:mount -t 文件系统类型 设备名 装载目录 文件系统类型就是分区格式,Linux支持的文件系统类型有许多: msdos DOS分区文件系统类型 vfat 支持长文件名的DOS分区文件(可以理解为Windows文

转:linux下安装或升级GCC4.8,以支持C++11标准

转:http://www.cnblogs.com/lizhenghn/p/3550996.html C++11标准在2011年8月份获得一致通过,这是自1998年后C++语言第一次大修订,对C++语言进行了改进和扩充.随后各编译器厂商都各自实现或部分实现了C++中的特性. 如需查看各编译器对C++11的支持程度,请参看文章: 本文主要介绍在Linux系统下,如何升级GCC以支持C++11.目前来看GCC是对C++11支持程度最高最多的编译器,但需要GCC4.8及以上版本.  本文使用操作系统:C

Linux下1号进程的前世(kernel_init)今生(init进程)----Linux进程的管理与调度(六)

日期 内核版本 架构 作者 GitHub CSDN 2016-05-29 Linux-4.5 X86 & arm gatieme LinuxDeviceDrivers Linux进程管理与调度-之-进程的创建 前言 Linux下有3个特殊的进程,idle进程(PID=0), init进程(PID=1)和kthreadd(PID=2) * idle进程由系统自动创建, 运行在内核态 idle进程其pid=0,其前身是系统创建的第一个进程,也是唯一一个没有通过fork或者kernel_thread产