Страница 1 из 1

генератор пароля для чего угодно (например, wifi) сервером сертификатов Микротика

Добавлено: 28 окт 2020, 23:13
Sertik
{
:local new ([/certificate scep-server otp generate minutes-valid=0 as-value]->"password")
:put $new
#:interface wireless security-profiles set your_profile wpa2-pre-shared-key="$new"
}

Re: генератор пароля для чего угодно (например, wifi) сервером сертификатов Микротика

Добавлено: 29 окт 2020, 20:14
podarok66
Очень интересный вариант. Главное, малозатратный по ресурсам. Есть парочка заминок. Первое, пароль ну очень параноидальный, 20 символов. В реальности надо резать на поменьше. Второе, если пароли просто куда-то отсылаются, не стоит их оставлять на Тике жить в разделе OTP. Надо бы чистить вслед за генерацией. Но это скорее не Sertik'у , а тем, кто пойдёт по его следам.
Sertik, спасибо.

Re: генератор пароля для чего угодно (например, wifi) сервером сертификатов Микротика

Добавлено: 29 окт 2020, 20:57
Sertik
Честно скажу идея не моя, взята с англоязычного форума Микротик.
Насчет вытереть оттуда пароль - посмотрел из Винбокс - вроде как нельзя. Может как-то можно скриптом ?

Re: генератор пароля для чего угодно (например, wifi) сервером сертификатов Микротика

Добавлено: 30 окт 2020, 04:25
Kato
Удалить можно чеоез терминал
Список /certificate scep-server otp print
Удалить /certificate scep-server otp remove numbers=0 (порядковый номер)

Re: генератор пароля для чего угодно (например, wifi) сервером сертификатов Микротика

Добавлено: 10 ноя 2020, 13:35
Sertik
Стирает все из скрипта спокойно

/certificate scep-server otp remove [/certificate scep-server otp find]

Re: генератор пароля для чего угодно (например, wifi) сервером сертификатов Микротика

Добавлено: 17 ноя 2020, 10:57
Sertik
Вот тут https://forum.mikrotik.com/viewtopic.php?f=9&t=169030 чувак пошёл дальше по той же теме. Можно пользоваться ...

Кроме того, в скрипте есть интересные приемы "скриптописания", которые могут оказаться полезными всем любителям ваяния скриптов ....

Кстати иностранцы уже подметили моё :if ([:len $0] = 0) do={ и пользуются этим для блокировки ошибочного вызова функций, ещё не исправленного в РОС.

Код: Выделить всё

##########################################################################################################################
# Written for RouterOS from Mikrotik
# Written by Msatter (alias on forum.mikrotik.com) 
# only for non commercial use
# Version 20201115-2.50
# generate password and store it all locally (function and variables to gain security)
# Extra external function called mixBase which mix-up the base string used
{
:global genpassword do={
  : if ([:len $0] = 0) do={:log warning "genpassword ran without a \$0 containing the name of the function"; :error "Exiting function due to a empty \$0"};
  :local arrayString [:toarray ""];

#:global mixBase; # define global function to be called 
# Local function to mix the content of the string/numberset and return that
:local mixBase do={
 :set $baseString $1;
 :if ([:len $baseString] < 4) do={:return $baseString}; # sanity check if there atleast is something to be mixed
 :set $baseLength (([:len $baseString] + 9) / 10); # each retrieved OTP hash, contains 10 HEX values

# Generate enough times hash to have enough characters to fit the password.
 :for j from=1 to=$baseLength do={
   # Generate 2 hashes of each 10 HEX values
   :set $hashA "$hash$([/certificate scep-server otp generate minutes-valid=0 as-value]->"password")"
   :set $hashB "$hash$([/certificate scep-server otp generate minutes-valid=0 as-value]->"password")"
   /certificate scep-server otp remove [find where password=$hashA];
   /certificate scep-server otp remove [find where password=$hashB];

# Calculate which specific mix is going to be used
   :set $selPos ("0x$[:pick $hashA 0 2 ]" / 27); # 0..9
   :set $selMix ("0x$[:pick $hashB $selPos ($selPos+2)]" / 37); # 0..7

# Debug
#:put "BaseLength:$baseLength Pos:$selPos Mix:$selMix"

# Group hashes in pairs. Substracting one because it starts a zero.
     :for i from=0 to=19 step=2 do={     
        :set $hexA "0x$[:pick $hashA $i ($i+2)]"
   	:set $hexB "0x$[:pick $hashB $i ($i+2)]"
   	:set $hexA ($hexA / 2); # prefers lower half of the $baseString for $hashA
     
     	:set $hexA (($hexA * 10000000000000000) / (2550000000000000000  / ([:len $baseString]))); # @ look no decimals max. 9223372036854775553
     	:set $hexB (($hexB * 10000000000000000) / (2550000000000000000  / ([:len $baseString]))); # @ look no decimals

# swapping $HexA and $HexB so that HexA has always the lowest value of the two
	:if ($hexA > $hexB) do={:set $tempHexA $hexA; :set $hexA $hexB; :set $hexB $tempHexA}; 
		
# Switch the values in the $baseString but not if the hex values are equal
       :if (($hexA != $hexB) || ($hexA>0) || ($hexB<160)) do={
	:set $baseA  "$[:pick $baseString 0 ($hexA-1)]"
        :set $baseAA "$[:pick $baseString ($hexA-1) $hexA]"
        :set $baseC  "$[:pick $baseString ($hexA) ($hexB-1)]"
        :set $baseB  "$[:pick $baseString ($hexB) [:len $baseString]]"
	:set $baseBB "$[:pick $baseString ($hexB-1) $hexB]"
	
	# Use different sequences and this one is for four round but it can be easily extended
	:if ($selMix=0)  do={:set $baseString "$baseA$baseBB$baseB$baseAA$baseC"}; # A/BB/B/AA/C
	:if ($selMix=1)  do={:set $baseString "$baseB$baseBB$baseA$baseAA$baseC"}; # B/BB/A/AA/C
	:if ($selMix=2)  do={:set $baseString "$baseC$baseBB$baseB$baseAA$baseA"}; # C/BB/B/AA/A
	:if ($selMix=3)  do={:set $baseString "$baseBB$baseB$baseA$baseC$baseAA"}; # BB/B/A/C/AA
	:if ($selMix=4)  do={:set $baseString "$baseAA$baseB$baseA$baseC$baseBB"}; # AA/B/A/C/BB
	:if ($selMix=5)  do={:set $baseString "$baseBB$baseC$baseA$baseB$baseAA"}; # BB/C/A/B/AA
	:if ($selMix>=6) do={:set $baseString "$baseBB$baseB$baseC$baseA$baseAA"}; # BB/B/C/A/AA
	
       }; # if ($hexA....
     }; # for i
  }; # for j
# return the mixed baseString  
 :return $baseString
}; # :local mixBase... [function]


### End mixBase########################

# Sets the length of the password
 :if ([:typeof [:tonum $1]]="nil") do={:set $pwdLength 10} else={:set $pwdLength $1}
# When no length is stated shift the parameters to their expected place when stated
 :if ([:typeof [:tonum $1]]="nil") do={:set $4 $3; :set $3 $2; :set $2 $1; :set $1}

# Always create pairs of HEX when the any parameter contains the word "hash"
 :foreach varname in={"$2"; "$3"; "$4"} do={:if ($varname ~ "hash") do={:set $pwdLength ($pwdLength - ($pwdLength % 2))} }

# From these strings the password is formed. They are stored in a array.
 :set ($arrayString->"default")      "!&()*+/0123456789:;<=>@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]abcdefghijklmnopqrstuvwxyz{}"
 :set ($arrayString->"letters")      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
 :set ($arrayString->"pin")          "0123456789"
 :set ($arrayString->"numbers")      "0123456789"
 :set ($arrayString->"special")      "!&()*+/:;<=>@[]{}"
 :set ($arrayString->"dummyhash")    "0123456789ABCDEF"

# Select the string or combination of strings used to generate the password from. If no string provided select the default one in array
 :if ([:typeof $2] ~ "(nothing|nil)") do={:set $pwdComposedOf (get [$arrayString as-value]->"default"); } \
     else={:foreach labelName in={$2;$3;$4} do={:set $pwdComposedOf "$pwdComposedOf$(get [$arrayString as-value]->$labelName)"}
    
# Check if the parameters are matching the key(s) of the array. $compareLabel is adaptive to the number of strings.	
    :foreach label,dummy in=$arrayString do={:set $compareLabel "$compareLabel$label|"}    
    :set $compareLabel "$[:pick $compareLabel 0 ([:len $compareLabel]-1)]"; :set $compareLabel "($compareLabel)"    
    :foreach varname in={"$2"; "$3"; "$4"} do={:if ($varname ~ $compareLabel || [:typeof $varname]~"(nothing|nil)") do={} else={:set $pwdComposedOf "" } }
 }; # if ([typeof $2]....

# Mixing up the string to have each time different base for every password/pin generation run
 :if ([:len $pwdComposedOf] > 0) do={:set $pwdComposedOf [$mixBase $pwdComposedOf]}

# Only generate a password when there is a string present in $pwdComposedOf. Else throw an on-error. It not a perfect check.
 :if ([:len $pwdComposedOf] > 0) do={
# Generate OTP enough times hash to have enough characters to fit the password (x2).
   :for i from=1 to=(($pwdLength + 9) / 10) do={:set $hash "$hash$([/certificate scep-server otp generate minutes-valid=0 as-value]->"password")"}
   /certificate scep-server otp remove [ find where password=$hash];
# Group them each time in pairs. Substracting 1 because it starts a zero.
   :for i from=0 to=(($pwdLength * 2)-1) step=2 do={
	:set $hex "0x$[:pick $hash $i ($i+2)]"
	:set $hex (($hex * 10000000000000000) / (2550000000000000000  / ([:len $pwdComposedOf]))); # Times 10000000000000000 to increase calculating accuracy. @no-decimals
	:set $pwdString "$pwdString$[:pick $pwdComposedOf ($hex) ($hex+1)]"
   }; # for i
   
# Compensate if the string is being too short
 :set $addToString  ($pwdLength - [:len $pwdString])
 :set $middleString ($pwdLength / 2) 
 :if ($addToString>0) do={:set $pwdString "$pwdString$[:pick $pwdString $middleString ($middleString + $addToString)]"}

# Debug
#:put "short:$addToString"
   
/certificate scep-server otp remove [find where expires < 10m]; # much better

   #:log info "Generated password: $pwdString with a length of $pwdLength"
   :return $pwdString
} \
else={
:foreach label,dummy in=$arrayString do={:set $parameters "$parameters$label, "} 
 :set $parameters [:pick $parameters 0 ([:len $parameters]-2)]
 :error "\r\nInvalid parameter(s) used. No password generated. Valid parameters are:\r\n$parameters" }
 
}; # :local genpassword (function)

# Create a mini-me or dedicated looped function
:global genpin do={
:global genpassword
:if ([:typeof [:tonum $1]] = "nil") do={:set $1 4}
:return [$genpassword [:tonum $1] numbers]
}; # :global $genpin
# Create a mini-me or dedicated looped function, creating even pairs of HEX
:global dummyhash do={
:global genpassword
:if ([:typeof [:tonum $1]] = "nil") do={:set $1 4}
:return [$genpassword [:tonum $1] dummyhash]
}; # :global $dummyhash
}