当您使用用户名和密码对服务进行身份验证时,强密码非常重要。一个强密码必须至少有14个字符,并有大小写字母和字母等变体。大多数时候,长密码被认为比短密码安全得多,因为它很难获得。
下面我们将学习使用Linux命令行创建安全密码的多种方法。我们将研究使用Linux命令行创建更强、更安全的密码的多种不同方法。如果要使用命令行创建强密码,可以使用多种方法和实用程序。我们将讨论其中的许多方法,可以根据需要选择其中一种方法来创建密码。
使用urandom生成密码
我们用来生成密码的第一个命令已经用tr命令过滤了/dev/urandom输出。这将允许我们删除所有不需要的字符,然后帮助我们只打印前14个字符。
cat /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c 14;echo
上述命令的输出如下:
输出允许我们仅通过删除所有不需要的字符来打印前14个字符。
...
void gendigit(int size)
{
...
f = fopen("/dev/urandom", "r");
for (i=0; i<size; i++)
{
fread(&randval, sizeof(randval), 1, f);
pass[i] = list[randval % 10];
printf("%c", pass[i]);
}
...
}
int main(int argc, char *argv[])
{
...
switch (argc)
{
case 1: genalpha(length); break;
case 2:
if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))
{
HELP
}
length = atoi(argv[1]);
if (length < 6 || length > 32)
{
printf("Error: Password size must be a number between 6 and 32\n\n");
HELP
}
genalpha(length); break;
case 3:
length = atoi(argv[2]);
if(length < 6 || length > 32)
{
printf("Error: Password size must be a number between 6 and 32\n\n");
HELP
}
/* 检查正在传递的参数 */
if (!strcmp(argv[1], "-s") || !strcmp(argv[1], "--symbol"))
{
gensymbol(length);
}
else if (!strcmp(argv[1], "-a") || !strcmp(argv[1], "--alphanum"))
{
genalpha(length);
}
else if (!strcmp(argv[1], "-d") || !strcmp(argv[1], "--digits"))
{
gendigit(length);
}
else {
HELP
}
break;
default: HELP
}
}
...
运行结果:
使用SHA生成密码
我们将在这个方法中使用SHA,它被设计用来使用 SHA-256 算法(SHA-2 系列,摘要长度为 256 位)校验数据完整性。
date | sha256sum
...
void sha256(const char* str)
{
unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, str, strlen(str));
SHA256_Final(hash, &sha256);
for(int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
printf("%02x", (int)hash[i]);
}
printf("\n");
}
int main(int argc, char *argv[])
{
sha256("asdfqwr12");
return 0;
}
编译运行:
通过md5sum简单的方式生成密码
使用命令行可以很容易地生成密码。虽然它不是随机的,但如果我们使用整个密码,它仍然很有用。为此,最简单的命令如下:
date | md5sum
一种获取可用作密码的随机字符串的方法是计算 MD5 校验值!校验值看起来确实像是随机字符串组合在一起,我们可以用作密码。确保你的计算源是个变量,这样的话每次运行命令时生成的校验值都不一样。date 命令 总会生成不同的输出。
static void Transform (UINT4 *buf, UINT4 *in) {
UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
#define S11 7
#define S12 12
#define S13 17
#define S14 22
FF ( a, b, c, d, in[ 0], S11, 3614090360UL);
FF ( d, a, b, c, in[ 1], S12, 3905402710UL);
FF ( c, d, a, b, in[ 2], S13, 606105819);
FF ( b, c, d, a, in[ 3], S14, 3250441966UL);
FF ( a, b, c, d, in[ 4], S11, 4118548399UL);
FF ( d, a, b, c, in[ 5], S12, 1200080426);
FF ( c, d, a, b, in[ 6], S13, 2821735955UL);
FF ( b, c, d, a, in[ 7], S14, 4249261313UL);
FF ( a, b, c, d, in[ 8], S11, 1770035416);
FF ( d, a, b, c, in[ 9], S12, 2336552879UL);
FF ( c, d, a, b, in[10], S13, 4294925233UL);
FF ( b, c, d, a, in[11], S14, 2304563134UL);
FF ( a, b, c, d, in[12], S11, 1804603682);
FF ( d, a, b, c, in[13], S12, 4254626195UL);
FF ( c, d, a, b, in[14], S13, 2792965006UL);
FF ( b, c, d, a, in[15], S14, 1236535329);
#define S21 5
#define S22 9
#define S23 14
#define S24 20
GG ( a, b, c, d, in[ 1], S21, 4129170786UL);
GG ( d, a, b, c, in[ 6], S22, 3225465664UL);
GG ( c, d, a, b, in[11], S23, 643717713);
GG ( b, c, d, a, in[ 0], S24, 3921069994UL);
GG ( a, b, c, d, in[ 5], S21, 3593408605UL);
GG ( d, a, b, c, in[10], S22, 38016083);
GG ( c, d, a, b, in[15], S23, 3634488961UL);
GG ( b, c, d, a, in[ 4], S24, 3889429448UL);
GG ( a, b, c, d, in[ 9], S21, 568446438);
GG ( d, a, b, c, in[14], S22, 3275163606UL);
GG ( c, d, a, b, in[ 3], S23, 4107603335UL);
GG ( b, c, d, a, in[ 8], S24, 1163531501);
GG ( a, b, c, d, in[13], S21, 2850285829UL);
GG ( d, a, b, c, in[ 2], S22, 4243563512UL);
GG ( c, d, a, b, in[ 7], S23, 1735328473);
GG ( b, c, d, a, in[12], S24, 2368359562UL);
#define S31 4
#define S32 11
#define S33 16
#define S34 23
HH ( a, b, c, d, in[ 5], S31, 4294588738UL);
HH ( d, a, b, c, in[ 8], S32, 2272392833UL);
HH ( c, d, a, b, in[11], S33, 1839030562);
HH ( b, c, d, a, in[14], S34, 4259657740UL);
HH ( a, b, c, d, in[ 1], S31, 2763975236UL);
HH ( d, a, b, c, in[ 4], S32, 1272893353);
HH ( c, d, a, b, in[ 7], S33, 4139469664UL);
HH ( b, c, d, a, in[10], S34, 3200236656UL);
HH ( a, b, c, d, in[13], S31, 681279174);
HH ( d, a, b, c, in[ 0], S32, 3936430074UL);
HH ( c, d, a, b, in[ 3], S33, 3572445317UL);
HH ( b, c, d, a, in[ 6], S34, 76029189);
HH ( a, b, c, d, in[ 9], S31, 3654602809UL);
HH ( d, a, b, c, in[12], S32, 3873151461UL);
HH ( c, d, a, b, in[15], S33, 530742520);
HH ( b, c, d, a, in[ 2], S34, 3299628645UL);
#define S41 6
#define S42 10
#define S43 15
#define S44 21
II ( a, b, c, d, in[ 0], S41, 4096336452UL);
II ( d, a, b, c, in[ 7], S42, 1126891415);
II ( c, d, a, b, in[14], S43, 2878612391UL);
II ( b, c, d, a, in[ 5], S44, 4237533241UL);
II ( a, b, c, d, in[12], S41, 1700485571);
II ( d, a, b, c, in[ 3], S42, 2399980690UL);
II ( c, d, a, b, in[10], S43, 4293915773UL);
II ( b, c, d, a, in[ 1], S44, 2240044497UL);
II ( a, b, c, d, in[ 8], S41, 1873313359);
II ( d, a, b, c, in[15], S42, 4264355552UL);
II ( c, d, a, b, in[ 6], S43, 2734768916UL);
II ( b, c, d, a, in[13], S44, 1309151649);
II ( a, b, c, d, in[ 4], S41, 4149444226UL);
II ( d, a, b, c, in[11], S42, 3174756917UL);
II ( c, d, a, b, in[ 2], S43, 718787259);
II ( b, c, d, a, in[ 9], S44, 3951481745UL);
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
}
void MD5Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen) {
UINT4 in[16];
int mdi;
unsigned int i, ii;
mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
mdContext->i[1]++;
mdContext->i[0] += ((UINT4)inLen << 3);
mdContext->i[1] += ((UINT4)inLen >> 29);
while (inLen--) {
mdContext->in[mdi++] = *inBuf++;
if (mdi == 0x40) {
for (i = 0, ii = 0; i < 16; i++, ii += 4)
in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
(((UINT4)mdContext->in[ii+2]) << 16) |
(((UINT4)mdContext->in[ii+1]) << 8) |
((UINT4)mdContext->in[ii]);
Transform (mdContext->buf, in);
mdi = 0;
}
}
}
void MD5Final (MD5_CTX *mdContext) {
UINT4 in[16];
int mdi;
unsigned int i, ii;
unsigned int padLen;
in[14] = mdContext->i[0];
in[15] = mdContext->i[1];
mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
MD5Update (mdContext, PADDING, padLen);
for (i = 0, ii = 0; i < 14; i++, ii += 4)
in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
(((UINT4)mdContext->in[ii+2]) << 16) |
(((UINT4)mdContext->in[ii+1]) << 8) |
((UINT4)mdContext->in[ii]);
Transform (mdContext->buf, in);
for (i = 0, ii = 0; i < 4; i++, ii += 4) {
mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
mdContext->digest[ii+1] = (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
mdContext->digest[ii+2] = (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
mdContext->digest[ii+3] = (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
}
}
static void MDPrint (MD5_CTX *mdContext) {
sprintf(master_pass,"%02x%02x%02x%02x",
mdContext->digest[0],
mdContext->digest[1],
mdContext->digest[2],
mdContext->digest[3]);
}
...
int main (int argn, char **argv)
{
if (argn < 2)
usage(*argv);
MDString(*(++argv));
printf("\nPassword Master: %s\n\n", master_pass);
return 0;
}
运行结果:
使用openssl生成密码
Linux中有几种方法可以为Linux命令行创建和生成密码。我们正在尝试的第一个方法是使用openssl。用于生成更强密码的命令包括openssl rand函数。这将帮助我们在一个字符串中生成14个随机字符。命令是:
openssl rand -base64 14
#include
#include
...
static char symbols[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'S',
'R', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b',
'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
'l', 'm', 'n', 'o', 'p', 'q', 's', 'r', 'u',
'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4',
'5', '6', '7', '8', '9', '0', '!', '~', '@',
'#', '$', '%', '<', '>', ';', '^', '&', '*',
'(', ')', '-', '+', '=', '_', '?', '|', '/'
};
int get_random_ascii_string(char *str, size_t in_size, generator_mode_t mode) {
...
switch (mode)
{
case FULL_ASCII_MODE:
boundary = sizeof(symbols);
break;
case SHORT_ASCII_MODE:
boundary = sizeof(symbols) - 21;
break;
default:
return EXIT_FAILURE;
}
if (gen_random_bytes(buffer, in_size) != EXIT_SUCCESS)
{
return EXIT_FAILURE;
}
for (size_t i = 0; i < in_size; ++i)
{
index = buffer[i];
/* 转换间隔的随机数 */
index %= boundary;
str[i] = symbols[index];
if ((i + 1) == in_size) {
str[(i + 1)] = '\0';
}
}
...
}
int main(int argc, char *const argv[])
{
...
rv = parse_argv(argc, argv);
if (rv)
{
fprintf(stderr, "openssl_pg: invalid option -- \"%s\"\n", argv[rv]);
show_help_info();
return 1;
}
if (show_help)
{
show_help_info();
return 0;
}
if (!result_len)
{
fprintf(stderr, "You need to specify password length\n");
return 1;
}
else if (result_len < 0)
{
fprintf(stderr, "Password length must be positive number\n");
return 1;
}
else if (result_len > MAX_PASSWDLEN)
{
fprintf(stderr, "Length of password is too big.\n");
return 1;
}
if (without_spec)
{
err = get_random_ascii_string(buf, result_len, SHORT_ASCII_MODE);
}
else
{
err = get_random_ascii_string(buf, result_len, FULL_ASCII_MODE);
}
if (err != EXIT_SUCCESS)
{
fprintf(stderr, "Failed to generate random bytes.\n");
return EXIT_FAILURE;
}
fprintf(stdout, "%s\n", buf);
explicit_memzero(buf, result_len);
...
}
运行结果:
If you need the complete source code, please add the WeChat number (c17865354792)
总结
我们讨论了几个从Linux命令行生成密码的方法。在本文中,我们讨论了实用程序openssh、urandom、md5sum、sha256sum。所有这些命令都可以保证从Linux命令行生成更强的密码,并且对用户确保系统安全非常有用。
Welcome to follow WeChat official account【程序猿编码】